public override async void BlockchainStartup(int blockchainId, BlockchainType blockchain, BlockchainNetwork network) { string websocketsUrl; string rpcUrl; await using (var connection = new MySqlConnection(OTHubSettings.Instance.MariaDB.ConnectionString)) { rpcUrl = await connection.ExecuteScalarAsync <string>(@"SELECT BlockchainNodeUrl FROM Blockchains where id = @id", new { id = blockchainId }); websocketsUrl = await connection.ExecuteScalarAsync <string>(@"SELECT BlockchainWebSocketsUrl FROM Blockchains where id = @id", new { id = blockchainId }); } Console.WriteLine(blockchain + " RPC: " + rpcUrl); Console.WriteLine(blockchain + " WS: " + websocketsUrl); if (string.IsNullOrWhiteSpace(websocketsUrl)) { return; } #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed Task.Run(async() => await WebSocketsManager.Start(blockchainId, websocketsUrl, rpcUrl, blockchain, network)); #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed }
public static async Task Start(int blockchainID, string webSocketsUrl, string rpcUrl, BlockchainType blockchainType, BlockchainNetwork blockchainNetwork) { bool failed = await Run(blockchainID, webSocketsUrl, rpcUrl, blockchainType, blockchainNetwork); if (failed) { _ = Task.Run(() => Start(blockchainID, webSocketsUrl, rpcUrl, blockchainType, blockchainNetwork)); } }
public async Task <string> GetLatestABIForContract([FromQuery] int blockchainID, [FromQuery] int contractType) { await using (var connection = new MySqlConnection(OTHubSettings.Instance.MariaDB.ConnectionString)) { var blockchainRow = await connection.QueryFirstAsync("SELECT * FROM blockchains where id = @id", new { id = blockchainID }); string blockchainName = blockchainRow.BlockchainName; string networkName = blockchainRow.NetworkName; BlockchainType blockchainEnum = Enum.Parse <BlockchainType>(blockchainName); BlockchainNetwork networkNameEnum = Enum.Parse <BlockchainNetwork>(networkName); return(AbiHelper.GetContractAbi((ContractTypeEnum)contractType, blockchainEnum, networkNameEnum)); } }
internal TaskControllerItem(BlockchainType blockchain, BlockchainNetwork network, Source source, TaskRunBlockchain task, TimeSpan runEveryTimeSpan, bool startNow, int blockchainID) { _blockchain = blockchain; _network = network; _source = source; _task = task; _runEveryTimeSpan = runEveryTimeSpan; _lastRunDateTime = startNow ? DateTime.MinValue : DateTime.Now; _systemStatus = new SystemStatus(task.Name, blockchainID); using (var connection = new MySqlConnection(OTHubSettings.Instance.MariaDB.ConnectionString)) { _systemStatus.InsertOrUpdate(connection, null, NextRunDate, false, _task.ParentName).GetAwaiter().GetResult(); } task.BlockchainStartup(blockchainID, blockchain, network); }
private static async Task ProcessSmartContractEvent(int blockchainID, BlockchainType blockchainType, BlockchainNetwork blockchainNetwork, ContractTypeEnum type, EthApiService eth, FilterLog filterLog, FilterLog transaction, Web3 cl) { Logger.WriteLine(Source.BlockchainSync, "WebSockets: Processing " + type + " event on " + blockchainType + " " + transaction.TransactionHash); if (type == ContractTypeEnum.Holding) { await ProcessHoldingSmartContractEvent(blockchainID, blockchainType, blockchainNetwork, eth, filterLog, transaction, cl); } else if (type == ContractTypeEnum.Profile) { await ProcessProfileSmartContractEvent(blockchainID, blockchainType, blockchainNetwork, eth, filterLog, transaction, cl); } else if (type == ContractTypeEnum.Litigation) { await ProcessLitigationSmartContractEvent(blockchainID, blockchainType, blockchainNetwork, eth, filterLog, transaction, cl); } }
public Blockchain( Header headerGenesis, byte[] genesisBlockBytes, Dictionary <int, byte[]> checkpoints) { Network = new BlockchainNetwork(this); HeaderGenesis = headerGenesis; HeaderTip = headerGenesis; Checkpoints = checkpoints; HeaderIndex = new Dictionary <int, List <Header> >(); UpdateHeaderIndex(headerGenesis); UTXOTable = new UTXOTable(genesisBlockBytes); DirectoryInfo DirectoryBlockArchive = Directory.CreateDirectory(PathBlockArchive); LogFile = new StreamWriter("logArchiver", false); }
public static Task[] Schedule <TTask>(Source source, bool startNow) where TTask : TaskRunBlockchain, new() { using (var connection = new MySqlConnection(OTHubSettings.Instance.MariaDB.ConnectionString)) { var blockchains = connection.Query(@"SELECT * FROM blockchains WHERE enabled = 1").ToArray(); List <Task> tasks = new List <Task>(); foreach (var blockchain in blockchains) { TTask task = new TTask(); int id = blockchain.ID; string blockchainName = blockchain.BlockchainName; string networkName = blockchain.NetworkName; Logger.WriteLine(Source.BlockchainSync, $"Setting up processes for {blockchainName} {networkName}. Task is " + task.Name); BlockchainType blockchainEnum = Enum.Parse <BlockchainType>(blockchainName); BlockchainNetwork networkNameEnum = Enum.Parse <BlockchainNetwork>(networkName); TimeSpan interval = task.GetExecutingInterval(blockchainEnum); tasks.Add(Task.Run(async() => { TaskController controller = new TaskController(source); var item = new TaskControllerItem(blockchainEnum, networkNameEnum, controller._source, task, interval, startNow, id); controller._items.Add(item); await controller.Start(); })); } return(tasks.ToArray()); } }
public override async Task <bool> Execute(Source source, BlockchainType blockchain, BlockchainNetwork network) { await using (var connection = new MySqlConnection(OTHubSettings.Instance.MariaDB.ConnectionString)) { int blockchainID = await GetBlockchainID(connection, blockchain, network); return(await RunChildren(source, blockchain, network, blockchainID)); } }
public static async Task Execute(MySqlConnection connection, int blockchainID, BlockchainType blockchain, BlockchainNetwork network) { using (await LockManager.GetLock(LockType.ProcessJobs).Lock()) { if (blockchain == BlockchainType.xDai || blockchain == BlockchainType.Polygon) { OTContract_Holding_OfferCreated[] offersToCalcPriceFactor = OTContract_Holding_OfferCreated.GetWithoutEstimatedPriceFactor(connection, blockchainID); foreach (OTContract_Holding_OfferCreated offer in offersToCalcPriceFactor) { (decimal lambda, int confidence)priceFactor = GetPriceFactor(offer.HoldingTimeInMinutes, offer.TokenAmountPerHolder, offer.GasPrice, offer.DataSetSizeInBytes); await OTOffer.UpdateLambda(connection, offer.BlockchainID, offer.OfferID, priceFactor.lambda, priceFactor.confidence); } } OTContract_Holding_OfferCreated[] offersToAdd = OTContract_Holding_OfferCreated.GetUnprocessed(connection, blockchainID); if (offersToAdd.Any()) { Console.WriteLine("Found " + offersToAdd.Length + " unprocessed offer created events."); } foreach (var offerToAdd in offersToAdd) { OTOffer offer = new OTOffer { CreatedTimestamp = offerToAdd.Timestamp, OfferID = offerToAdd.OfferID, CreatedTransactionHash = offerToAdd.TransactionHash, CreatedBlockNumber = offerToAdd.BlockNumber, DCNodeId = offerToAdd.DCNodeId, DataSetId = offerToAdd.DataSetId, DataSetSizeInBytes = offerToAdd.DataSetSizeInBytes, HoldingTimeInMinutes = offerToAdd.HoldingTimeInMinutes, IsFinalized = false, LitigationIntervalInMinutes = offerToAdd.LitigationIntervalInMinutes, TransactionIndex = offerToAdd.TransactionIndex, TokenAmountPerHolder = offerToAdd.TokenAmountPerHolder, BlockchainID = blockchainID }; //ETH has dynamic tracInBaseCurrency which is more annoying to implement if (blockchain == BlockchainType.xDai || blockchain == BlockchainType.Polygon) { (decimal lambda, int confidence)priceFactor = GetPriceFactor(offer.HoldingTimeInMinutes, offer.TokenAmountPerHolder, offerToAdd.GasPrice, offer.DataSetSizeInBytes); offer.EstimatedLambda = priceFactor.lambda; offer.EstimatedLambdaConfidence = priceFactor.confidence; } OTOffer.InsertIfNotExist(connection, offer); OTContract_Holding_OfferCreated.SetProcessed(connection, offerToAdd); } OTContract_Holding_OfferFinalized[] offersToFinalize = OTContract_Holding_OfferFinalized.GetUnprocessed(connection, blockchainID); if (offersToFinalize.Any()) { Console.WriteLine("Found " + offersToFinalize.Length + " unprocessed offer finalized events."); } foreach (OTContract_Holding_OfferFinalized offerToFinalize in offersToFinalize) { await OTOffer.FinalizeOffer(connection, offerToFinalize.OfferID, offerToFinalize.BlockNumber, offerToFinalize.TransactionHash, offerToFinalize.Holder1, offerToFinalize.Holder2, offerToFinalize.Holder3, offerToFinalize.Timestamp, blockchainID); OTContract_Holding_OfferFinalized.SetProcessed(connection, offerToFinalize); } if (offersToFinalize.Any()) { RabbitMqService.OfferFinalized(offersToFinalize.Select(offerToFinalize => new OfferFinalizedMessage { OfferID = offerToFinalize.OfferID, BlockchainID = blockchainID, Timestamp = offerToFinalize.Timestamp, Holder1 = offerToFinalize.Holder1, Holder2 = offerToFinalize.Holder2, Holder3 = offerToFinalize.Holder3 })); } } }
public override async Task <bool> Execute(Source source, BlockchainType blockchain, BlockchainNetwork network) { ClientBase.ConnectionTimeout = new TimeSpan(0, 0, 5, 0); using (var connection = new MySqlConnection(OTHubSettings.Instance.MariaDB.ConnectionString)) { //OTContract litigationStorageContract = OTContract.GetByType(connection, (int) ContractType.LitigationStorage).FirstOrDefault(c => c.IsLatest); //Contract storageContract = new Contract((EthApiService)cl.Eth, Constants.GetContractAbi(ContractType.LitigationStorage), litigationStorageContract.Address); // Function getLitigationStatusFunction = storageContract.GetFunction("getLitigationStatus"); int blockchainID = await GetBlockchainID(connection, blockchain, network); var cl = await GetWeb3(connection, blockchainID, blockchain); var eth = new EthApiService(cl.Client); foreach (var contract in await OTContract.GetByTypeAndBlockchain(connection, (int)ContractTypeEnum.Replacement, blockchainID)) { if (contract.IsArchived && contract.LastSyncedTimestamp.HasValue && (DateTime.Now - contract.LastSyncedTimestamp.Value).TotalDays <= 5) { #if DEBUG Logger.WriteLine(source, " Skipping contract: " + contract.Address); #endif continue; } Logger.WriteLine(source, " Using contract: " + contract.Address); var holdingContract = new Contract(eth, AbiHelper.GetContractAbi(ContractTypeEnum.Replacement, blockchain, network), contract.Address); var replacementCompletedEvent = holdingContract.GetEvent("ReplacementCompleted"); ulong size = (ulong)10000; BlockBatcher batcher = BlockBatcher.Start(contract.SyncBlockNumber, (ulong)LatestBlockNumber.Value, size, async delegate(ulong start, ulong end) { await Sync(source, replacementCompletedEvent, contract, connection, cl, blockchainID, eth, start, end); }); await batcher.Execute(); } } return(true); }
public static async Task <BeforePayoutResult> CanTryPayout(string nodeID, string offerId, string holdingAddress, string holdingStorageAddress, string litigationStorageAddress, string identity, int?blockchainID, string selectedAddress) { if (nodeID == null || offerId == null || holdingAddress == null || holdingStorageAddress == null || litigationStorageAddress == null || identity == null || blockchainID == null || selectedAddress == null) { return(new BeforePayoutResult { CanTryPayout = false, Header = "Stop!", Message = "Missing data in request." }); } await using (var connection = new MySqlConnection(OTHubSettings.Instance.MariaDB.ConnectionString)) { var holdingStorageAddressModel = await connection.QueryFirstOrDefaultAsync <ContractAddress>(ContractsSql.GetHoldingStorageAddressByAddress, new { holdingStorageAddress = holdingStorageAddress, blockchainID }); holdingStorageAddress = holdingStorageAddressModel?.Address; if (holdingStorageAddress == null) { return(new BeforePayoutResult { CanTryPayout = false, Header = "Stop!", Message = "OT Hub is not familiar with this holding storage smart contract address for this blockchain id " + blockchainID }); } var blockchainRow = await connection.QueryFirstAsync("SELECT * FROM blockchains where id = @id", new { id = blockchainID }); string blockchainName = blockchainRow.BlockchainName; string networkName = blockchainRow.NetworkName; string explorerTransactionUrl = blockchainRow.TransactionUrl; BlockchainType blockchainEnum = Enum.Parse <BlockchainType>(blockchainName); BlockchainNetwork networkNameEnum = Enum.Parse <BlockchainNetwork>(networkName); string nodeUrl = await connection.ExecuteScalarAsync <string>(@"SELECT BlockchainNodeUrl FROM blockchains WHERE id = @id", new { id = blockchainID }); var cl = new Web3(nodeUrl); var eth = new EthApiService(cl.Client); var ercContract = new Contract(eth, AbiHelper.GetContractAbi(ContractTypeEnum.ERC725, blockchainEnum, networkNameEnum), identity); Function keyHasPurposeFunction = ercContract.GetFunction("keyHasPurpose"); var abiEncode = new ABIEncode(); byte[] test = abiEncode.GetABIEncodedPacked(selectedAddress.HexToByteArray()); byte[] bytes = CalculateHash(test); bool hasPermission = await keyHasPurposeFunction.CallAsync <bool>(bytes, 1) || await keyHasPurposeFunction.CallAsync <bool>(bytes, 2); if (!hasPermission) { return(new BeforePayoutResult { CanTryPayout = false, Header = "Stop!", Message = "The address you have selected in MetaMask (" + selectedAddress + ") does not have permission to payout on the identity " + identity + ". You need to pick either your management wallet or operational wallet." }); } var holdingStorageAbi = AbiHelper.GetContractAbi(ContractTypeEnum.HoldingStorage, blockchainEnum, networkNameEnum); holdingAddress = (await connection.QueryFirstOrDefaultAsync <ContractAddress>(ContractsSql.GetHoldingAddressByAddress, new { holdingAddress = holdingAddress, blockchainID }))?.Address; if (holdingAddress == null) { return(new BeforePayoutResult { CanTryPayout = false, Header = "Stop!", Message = "OT Hub is not familiar with this holding smart contract address for this blockchain id " + blockchainID }); } var offerIdArray = offerId.HexToByteArray(); var holdingStorageContract = new Contract(new EthApiService(cl.Client), holdingStorageAbi, holdingStorageAddress); var getHolderStakedAmountFunction = holdingStorageContract.GetFunction("getHolderStakedAmount"); var holderStakedAmount = await getHolderStakedAmountFunction.CallAsync <BigInteger>(offerIdArray, identity); var getHolderPaymentTimestampFunction = holdingStorageContract.GetFunction("getHolderPaymentTimestamp"); var holderPaymentTimestamp = await getHolderPaymentTimestampFunction.CallAsync <BigInteger>(offerIdArray, identity); var getOfferHoldingTimeInMinutesFunction = holdingStorageContract.GetFunction("getOfferHoldingTimeInMinutes"); var offerHoldingTimeInMinutes = await getOfferHoldingTimeInMinutesFunction.CallAsync <BigInteger>(offerIdArray); var getHolderPaidAmountFunction = holdingStorageContract.GetFunction("getHolderPaidAmount"); var holderPaidAmount = await getHolderPaidAmountFunction.CallAsync <BigInteger>(offerIdArray, identity); if (holderStakedAmount <= 0) { return(new BeforePayoutResult { CanTryPayout = false, Header = "Stop!", Message = "The smart contract says this identity did not hold data for this job. The transaction will likely fail if you try to send this manually." }); } //long holdingTime = await connection.ExecuteScalarAsync<long>( // @"select HoldingTimeInMinutes from otoffer where OfferID = @offerID and blockchainID = @blockchainID", // new // { // offerId, // blockchainID // }); var latestBlockParam = BlockParameter.CreateLatest(); var block = await cl.Eth.Blocks.GetBlockWithTransactionsByNumber.SendRequestAsync(latestBlockParam); DateTime blockDate = TimestampHelper.UnixTimeStampToDateTime((double)block.Timestamp.Value); DateTime jobStartDate = await connection.ExecuteScalarAsync <DateTime>(@"SELECT Timestamp FROM otcontract_holding_offerfinalized where OfferID = @offerID and BlockchainID = @blockchainID", new { offerID = offerId, blockchainID }); DateTime jobEndDate = jobStartDate.AddMinutes((int)offerHoldingTimeInMinutes); if (blockDate > jobEndDate) { blockDate = jobEndDate; } BigInteger blockTimestamp = new BigInteger(TimestampHelper.DateTimeToUnixTimeStamp(blockDate)); var amountToTransfer = holderStakedAmount; amountToTransfer = amountToTransfer * (blockTimestamp - holderPaymentTimestamp); amountToTransfer = amountToTransfer / (offerHoldingTimeInMinutes * 60); decimal friendlyEstimatedPayout = Web3.Convert.FromWei(amountToTransfer); if (holderPaidAmount == holderStakedAmount) { var friendlyAmount = Web3.Convert.FromWei(holderPaidAmount); return(new BeforePayoutResult { CanTryPayout = false, Header = "Stop!", Message = "The smart contract says you have been paid " + friendlyAmount + " TRAC for this job. The transaction will likely fail if you try to send this manually." }); } if (!String.IsNullOrWhiteSpace(litigationStorageAddress)) { litigationStorageAddress = (await connection.QueryFirstOrDefaultAsync <ContractAddress>(@"select Address from otcontract where Type = 9 AND Address = @litigationStorageAddress AND blockchainID = @blockchainID", new { litigationStorageAddress = litigationStorageAddress, blockchainID }))?.Address; if (litigationStorageAddress == null) { return(new BeforePayoutResult { CanTryPayout = false, Header = "Stop!", Message = "OT Hub is not familiar with this litigation storage smart contract address for this blockchain id " + blockchainID }); } Contract storageContract = new Contract((EthApiService)cl.Eth, AbiHelper.GetContractAbi(ContractTypeEnum.LitigationStorage, blockchainEnum, networkNameEnum), litigationStorageAddress); Function getLitigationStatusFunction = storageContract.GetFunction("getLitigationStatus"); Function getLitigationTimestampFunction = storageContract.GetFunction("getLitigationTimestamp"); BigInteger litigationTimestampInt = await getLitigationTimestampFunction.CallAsync <BigInteger>(latestBlockParam, offerIdArray, identity); Function getOfferLitigationIntervalInMinutesFunction = holdingStorageContract.GetFunction("getOfferLitigationIntervalInMinutes"); BigInteger litgationInterval = await getOfferLitigationIntervalInMinutesFunction.CallAsync <BigInteger>(latestBlockParam, offerIdArray) * 60; var status = await getLitigationStatusFunction.CallAsync <UInt16>(latestBlockParam, offerIdArray, identity); if (status == 1) //initiated { if (litigationTimestampInt + (litgationInterval * 2) >= block.Timestamp.Value) { return(new BeforePayoutResult { CanTryPayout = false, Header = "Stop!", Message = "The smart contract says 'Unanswered litigation in progress, cannot pay out'. The transaction will likely fail if you try to send this manually." }); } } else if (status == 2) //answered { if (litigationTimestampInt + (litgationInterval) >= block.Timestamp.Value) { return(new BeforePayoutResult { CanTryPayout = false, Header = "Stop!", Message = "The smart contract says 'Unanswered litigation in progress, cannot pay out'. The transaction will likely fail if you try to send this manually." }); } } else if (status == 0) //completed { //Do nothing as this is fine } else { return(new BeforePayoutResult { CanTryPayout = false, Header = "Stop!", Message = "The smart contract says 'Data holder is replaced or being replaced, cannot payout!'. The transaction will likely fail if you try to send this manually." }); } } return(new BeforePayoutResult { CanTryPayout = true, BlockchainExplorerUrlFormat = explorerTransactionUrl, EstimatedPayout = friendlyEstimatedPayout }); } }
public override async Task <bool> Execute(Source source, BlockchainType blockchain, BlockchainNetwork network) { await using (var connection = new MySqlConnection(OTHubSettings.Instance.MariaDB.ConnectionString)) { int blockchainID = await GetBlockchainID(connection, blockchain, network); var profiles = await OTContract.GetByTypeAndBlockchain(connection, (int)ContractTypeEnum.Profile, blockchainID); foreach (var otContract in profiles) { var dates = connection.Query <DateTime?>( @"select MAX(Timestamp) from otcontract_profile_identitycreated r join ethblock b on r.BlockNumber = b.BlockNumber AND b.BlockchainID = r.BlockchainID WHERE r.ContractAddress = @contract AND r.BlockchainID = @blockchainID union all select MAX(Timestamp) from otcontract_profile_identitytransferred r join ethblock b on r.BlockNumber = b.BlockNumber AND b.BlockchainID = r.BlockchainID WHERE r.ContractAddress = @contract AND r.BlockchainID = @blockchainID union all select MAX(Timestamp) from otcontract_profile_profilecreated r join ethblock b on r.BlockNumber = b.BlockNumber AND b.BlockchainID = r.BlockchainID WHERE r.ContractAddress = @contract AND r.BlockchainID = @blockchainID union all select MAX(Timestamp) from otcontract_profile_tokensdeposited r join ethblock b on r.BlockNumber = b.BlockNumber AND b.BlockchainID = r.BlockchainID WHERE r.ContractAddress = @contract AND r.BlockchainID = @blockchainID union all select MAX(Timestamp) from otcontract_profile_tokensreleased r join ethblock b on r.BlockNumber = b.BlockNumber AND b.BlockchainID = r.BlockchainID WHERE r.ContractAddress = @contract AND r.BlockchainID = @blockchainID union all select MAX(Timestamp) from otcontract_profile_tokensreserved r join ethblock b on r.BlockNumber = b.BlockNumber AND b.BlockchainID = r.BlockchainID WHERE r.ContractAddress = @contract AND r.BlockchainID = @blockchainID union all select MAX(Timestamp) from otcontract_profile_tokenstransferred r join ethblock b on r.BlockNumber = b.BlockNumber AND b.BlockchainID = r.BlockchainID WHERE r.ContractAddress = @contract AND r.BlockchainID = @blockchainID union all select MAX(Timestamp) from otcontract_profile_tokenswithdrawn r join ethblock b on r.BlockNumber = b.BlockNumber AND b.BlockchainID = r.BlockchainID WHERE r.ContractAddress = @contract AND r.BlockchainID = @blockchainID", new { contract = otContract.Address, blockchainID = blockchainID }).Where(d => d.HasValue).Select(d => d.Value).ToArray(); if (dates.Any()) { var maxDate = dates.Max(); if ((DateTime.Now - maxDate).TotalDays >= 30) { if (!otContract.IsArchived) { otContract.IsArchived = true; await OTContract.Update(connection, otContract, false, true); } } else { if (otContract.IsArchived) { otContract.IsArchived = false; await OTContract.Update(connection, otContract, false, true); } } } else { if (!otContract.IsArchived) { otContract.IsArchived = true; await OTContract.Update(connection, otContract, false, true); } } } profiles = await OTContract.GetByTypeAndBlockchain(connection, (int)ContractTypeEnum.Holding, blockchainID); foreach (var otContract in profiles) { var dates = (await connection.QueryAsync <DateTime?>(@"select MAX(Timestamp) from otcontract_holding_offertask r join ethblock b on r.BlockNumber = b.BlockNumber AND r.BlockchainID = b.BlockchainID WHERE r.ContractAddress = @contract AND b.BlockchainID = r.BlockchainID union all select MAX(Timestamp) from otcontract_holding_ownershiptransferred r join ethblock b on r.BlockNumber = b.BlockNumber AND b.BlockchainID = r.BlockchainID WHERE r.ContractAddress = @contract AND r.BlockchainID = @blockchainID union all select MAX(r.Timestamp) from otcontract_holding_paidout r join ethblock b on r.BlockNumber = b.BlockNumber AND b.BlockchainID = r.BlockchainID WHERE r.ContractAddress = @contract AND r.BlockchainID = @blockchainID", new { contract = otContract.Address, blockchainID = blockchainID })).Where(d => d.HasValue).Select(d => d.Value).ToArray(); if (dates.Any()) { var maxDate = dates.Max(); if ((DateTime.Now - maxDate).TotalDays >= 30) { if (!otContract.IsArchived) { otContract.IsArchived = true; await OTContract.Update(connection, otContract, false, true); } } else { if (otContract.IsArchived) { otContract.IsArchived = false; await OTContract.Update(connection, otContract, false, true); } } } else { if (!otContract.IsArchived) { otContract.IsArchived = true; await OTContract.Update(connection, otContract, false, true); } } } } return(true); }
private async Task ProcessJob(MySqlConnection connection, int blockchainID, OTIdentity[] identities, string address, BlockchainType blockchain, BlockchainNetwork network, Source source, uint id) { string abi = AbiHelper.GetContractAbi(ContractTypeEnum.ERC725, blockchain, network); string nodeUrl = await connection.ExecuteScalarAsync <string>(@"SELECT BlockchainNodeUrl FROM blockchains WHERE id = @id", new { id = blockchainID }); var cl = new Web3(nodeUrl); var eth = new EthApiService(cl.Client); Int32 percentage = 0; int counter = 0; foreach (OTIdentity identity in identities) { counter++; try { int loopPercentage = (int)Math.Round((decimal)counter * 100 / identities.Count(), MidpointRounding.AwayFromZero); if (loopPercentage != percentage) { percentage = loopPercentage; await connection.ExecuteAsync(@"UPDATE findnodesbywalletjob SET Progress = @percentage WHERE ID = @id", new { id = id, percentage }); } var ercContract = new Contract(eth, abi, identity.Identity); Function keyHasPurposeFunction = ercContract.GetFunction("keyHasPurpose"); var abiEncode = new ABIEncode(); byte[] data = abiEncode.GetABIEncodedPacked(address.HexToByteArray()); byte[] bytes = CalculateHash(data); await TimeConstraint; bool hasPermission = await keyHasPurposeFunction.CallAsync <bool>(bytes, 1); if (hasPermission) { await connection.ExecuteAsync(@"INSERT INTO findnodesbywalletresult(JobID, Identity) VALUES(@jobID, @identity)", new { jobID = id, identity = identity.Identity }); } } catch (Exception ex) { throw; } } await connection.ExecuteAsync(@"UPDATE findnodesbywalletjob SET Progress = 100, EndDate = @endDate WHERE ID = @id", new { id = id, endDate = DateTime.UtcNow }); }
public static async Task CreateMissingIdentities( MySqlConnection connection, Web3 cl, int blockchainId, BlockchainType blockchain, BlockchainNetwork network) { var eth = new EthApiService(cl.Client); var allIdentitiesCreated = connection .Query <OTContract_Profile_IdentityCreated>(@"select * from OTContract_Profile_IdentityCreated IC WHERE IC.NewIdentity not in (SELECT OTIdentity.Identity FROM OTIdentity WHERE BlockchainID = @BlockchainID) AND IC.BlockchainID = @blockchainID", new { blockchainId = blockchainId }) .ToArray(); foreach (var identity in allIdentitiesCreated) { var ercContract = new Contract(eth, AbiHelper.GetContractAbi(ContractTypeEnum.ERC725, blockchain, network), identity.NewIdentity); var otVersionFunction = ercContract.GetFunction("otVersion"); var value = await otVersionFunction.CallAsync <BigInteger>(); await OTIdentity.Insert(connection, new OTIdentity { TransactionHash = identity.TransactionHash, Identity = identity.NewIdentity, Version = (int)value, BlockchainID = blockchainId }); } //This only happens due to missing blockchain events (only happened in December 2018) var profilesCreatedWithoutIdentities = connection.Query( @"select TransactionHash, Profile from otcontract_profile_profilecreated WHERE Profile not in (select otidentity.Identity from otidentity WHERE BlockchainID = @blockchainID) AND BlockchainID = @blockchainID", new { blockchainId = blockchainId }).ToArray(); foreach (var profilesCreatedWithoutIdentity in profilesCreatedWithoutIdentities) { string hash = profilesCreatedWithoutIdentity.TransactionHash; string identity = profilesCreatedWithoutIdentity.Profile; var ercContract = new Contract(eth, AbiHelper.GetContractAbi(ContractTypeEnum.ERC725, blockchain, network), identity); var otVersionFunction = ercContract.GetFunction("otVersion"); var value = await otVersionFunction.CallAsync <BigInteger>(); await OTIdentity.Insert(connection, new OTIdentity { TransactionHash = hash, Identity = identity, Version = (int)value, BlockchainID = blockchainId }); } }
private static async Task ProcessProfileSmartContractEvent(int blockchainID, BlockchainType blockchainType, BlockchainNetwork blockchainNetwork, EthApiService eth, FilterLog filterLog, FilterLog transaction, Web3 cl) { var contract = new Contract(eth, AbiHelper.GetContractAbi(ContractTypeEnum.Profile, blockchainType, blockchainNetwork), filterLog.Address); var identityCreatedEvent = contract.GetEvent("IdentityCreated"); var profileCreatedEvent = contract.GetEvent("ProfileCreated"); var tokensDepositedEvent = contract.GetEvent("TokensDeposited"); var tokensReleasedEvent = contract.GetEvent("TokensReleased"); var tokensWithdrawnEvent = contract.GetEvent("TokensWithdrawn"); await using (var connection = new MySqlConnection(OTHubSettings.Instance.MariaDB.ConnectionString)) { try { if (identityCreatedEvent.IsLogForEvent(transaction)) { var events = identityCreatedEvent.DecodeAllEventsDefaultForEvent( new[] { filterLog }); foreach (EventLog <List <ParameterOutput> > eventLog in events) { await SyncProfileContractTask.ProcessIdentityCreated(connection, filterLog.Address, blockchainID, cl, eventLog, eth); } await SyncProfileContractTask.CreateMissingIdentities(connection, cl, blockchainID, blockchainType, blockchainNetwork); } if (profileCreatedEvent.IsLogForEvent(transaction)) { Function createProfileFunction = contract.GetFunction("createProfile"); var events = profileCreatedEvent.DecodeAllEventsDefaultForEvent( new[] { filterLog }); foreach (EventLog <List <ParameterOutput> > eventLog in events) { await SyncProfileContractTask.ProcessProfileCreated(connection, filterLog.Address, createProfileFunction, blockchainID, cl, eventLog, eth); } await SyncProfileContractTask.CreateMissingIdentities(connection, cl, blockchainID, blockchainType, blockchainNetwork); } if (tokensDepositedEvent.IsLogForEvent(transaction)) { var events = tokensDepositedEvent.DecodeAllEventsDefaultForEvent( new[] { filterLog }); foreach (var eventLog in events.GroupBy(t => t.Log.TransactionHash)) { await SyncProfileContractTask.ProcessTokensDeposited(connection, filterLog.Address, blockchainID, cl, eventLog, eth); } } if (tokensReleasedEvent.IsLogForEvent(transaction)) { var events = tokensReleasedEvent.DecodeAllEventsDefaultForEvent( new[] { filterLog }); foreach (var eventLog in events.GroupBy(t => t.Log.TransactionHash)) { await SyncProfileContractTask.ProcessTokensReleased(connection, filterLog.Address, blockchainID, cl, eventLog, eth); } } if (tokensWithdrawnEvent.IsLogForEvent(transaction)) { var events = tokensWithdrawnEvent.DecodeAllEventsDefaultForEvent( new[] { filterLog }); foreach (var eventLog in events.GroupBy(t => t.Log.TransactionHash)) { await SyncProfileContractTask.ProcessTokensWithdrawn(connection, filterLog.Address, blockchainID, cl, eventLog, eth); } } } catch (Exception ex) { Logger.WriteLine(Source.BlockchainSync, ex.ToString()); } } }
private static async Task ProcessLitigationSmartContractEvent(int blockchainID, BlockchainType blockchainType, BlockchainNetwork blockchainNetwork, EthApiService eth, FilterLog filterLog, FilterLog transaction, Web3 cl) { var contract = new Contract(eth, AbiHelper.GetContractAbi(ContractTypeEnum.Litigation, blockchainType, blockchainNetwork), filterLog.Address); var litigationInitiatedEvent = contract.GetEvent("LitigationInitiated"); var litigationAnsweredEvent = contract.GetEvent("LitigationAnswered"); var litigationTimedOutEvent = contract.GetEvent("LitigationTimedOut"); var litigationCompletedEvent = contract.GetEvent("LitigationCompleted"); var replacementStartedEvent = contract.GetEvent("ReplacementStarted"); await using (var connection = new MySqlConnection(OTHubSettings.Instance.MariaDB.ConnectionString)) { try { if (litigationInitiatedEvent.IsLogForEvent(transaction)) { var events = litigationInitiatedEvent.DecodeAllEventsDefaultForEvent( new[] { filterLog }); foreach (EventLog <List <ParameterOutput> > eventLog in events) { await SyncLitigationContractTask.ProcessLitigationInitiated(connection, blockchainID, cl, eventLog, eth); } } if (litigationAnsweredEvent.IsLogForEvent(transaction)) { var events = litigationAnsweredEvent.DecodeAllEventsDefaultForEvent( new[] { filterLog }); foreach (EventLog <List <ParameterOutput> > eventLog in events) { await SyncLitigationContractTask.ProcessLitigationAnswered(connection, blockchainID, cl, eventLog, eth); } } if (litigationTimedOutEvent.IsLogForEvent(transaction)) { var events = litigationTimedOutEvent.DecodeAllEventsDefaultForEvent( new[] { filterLog }); foreach (EventLog <List <ParameterOutput> > eventLog in events) { await SyncLitigationContractTask.ProcessLitigationTimedOut(connection, blockchainID, cl, eventLog, eth); } } if (litigationCompletedEvent.IsLogForEvent(transaction)) { var events = litigationCompletedEvent.DecodeAllEventsDefaultForEvent( new[] { filterLog }); foreach (EventLog <List <ParameterOutput> > eventLog in events) { await SyncLitigationContractTask.ProcessLitigationCompleted(connection, blockchainID, cl, eventLog, eth); } } if (replacementStartedEvent.IsLogForEvent(transaction)) { var events = replacementStartedEvent.DecodeAllEventsDefaultForEvent( new[] { filterLog }); foreach (EventLog <List <ParameterOutput> > eventLog in events) { await SyncLitigationContractTask.ProcessLitigationCompleted(connection, blockchainID, cl, eventLog, eth); } } } catch (Exception ex) { Logger.WriteLine(Source.BlockchainSync, ex.ToString()); } } }
private async Task PopulateSmartContracts(MySqlConnection connection, string hubAddress, bool isLatest, int blockchainID, BlockchainType blockchain, BlockchainNetwork network) { var web3 = await GetWeb3(connection, blockchainID, blockchain); EthApiService eth = new EthApiService(web3.Client); var hubContract = new Contract(eth, AbiHelper.GetContractAbi(ContractTypeEnum.Hub, blockchain, network), hubAddress); HubAddress hubAddressModel = await GetHubAddressModel(connection, hubAddress, blockchainID, isLatest); if (blockchain == BlockchainType.Ethereum && network == BlockchainNetwork.Mainnet) { await PopulateOriginalETHContracts(connection, blockchainID, hubAddressModel.FromBlockNumber); } Event contractsChangedEvent = hubContract.GetEvent("ContractsChanged"); ulong diff = (ulong)LatestBlockNumber.Value - hubAddressModel.SyncBlockNumber; ulong size = (ulong)10000; beforeSync: if (diff > size) { ulong currentStart = hubAddressModel.SyncBlockNumber; ulong currentEnd = currentStart + size; if (currentEnd > LatestBlockNumber.Value) { currentEnd = (ulong)LatestBlockNumber.Value; } bool canRetry = true; while (currentStart == 0 || currentStart < LatestBlockNumber.Value) { start: try { await SyncContractsChanged(contractsChangedEvent, currentStart, currentEnd, hubContract, web3, connection, blockchainID); } catch (RpcResponseException ex) when(ex.Message.Contains("query returned more than")) { size = size / 2; Logger.WriteLine(Source.BlockchainSync, "Swapping to block sync size of " + size); goto beforeSync; } catch (RpcClientUnknownException ex) when(canRetry && ex.GetBaseException().Message.Contains("Gateway")) { canRetry = false; goto start; } currentStart = currentEnd; currentEnd = currentStart + size; if (currentEnd > LatestBlockNumber.Value) { currentEnd = (ulong)LatestBlockNumber.Value; } } } else { await SyncContractsChanged(contractsChangedEvent, hubAddressModel.SyncBlockNumber, (ulong)LatestBlockNumber.Value, hubContract, web3, connection, blockchainID); } await SyncLatestContractsOnHub(hubAddressModel.FromBlockNumber, hubContract, connection, blockchainID, isLatest); }
public override async Task <bool> Execute(Source source, BlockchainType blockchain, BlockchainNetwork network) { ClientBase.ConnectionTimeout = new TimeSpan(0, 0, 5, 0); await using (var connection = new MySqlConnection(OTHubSettings.Instance.MariaDB.ConnectionString)) { int blockchainID = await GetBlockchainID(connection, blockchain, network); string currentHubAddress = await connection.ExecuteScalarAsync <string>("select HubAddress from blockchains where id = @id", new { id = blockchainID }); var allHubAddresses = new List <String>(); allHubAddresses.Add(currentHubAddress); var addresses = allHubAddresses.Distinct(); foreach (var address in addresses) { await PopulateSmartContracts(connection, address, address == currentHubAddress, blockchainID, blockchain, network); } } await SmartContractManager.Load(); return(true); }
public override async Task <bool> Execute(Source source, BlockchainType blockchain, BlockchainNetwork network) { ClientBase.ConnectionTimeout = new TimeSpan(0, 0, 5, 0); await using (var connection = new MySqlConnection(OTHubSettings.Instance.MariaDB.ConnectionString)) { int blockchainID = await GetBlockchainID(connection, blockchain, network); var cl = await GetWeb3(connection, blockchainID, blockchain); var profileStorageContractAddress = (await OTContract .GetByTypeAndBlockchain(connection, (int)ContractTypeEnum.ProfileStorage, blockchainID)).SingleOrDefault(a => a.IsLatest); if (profileStorageContractAddress == null) { return(false); } var profileStorageContract = new Contract(new EthApiService(cl.Client), AbiHelper.GetContractAbi(ContractTypeEnum.ProfileStorage, blockchain, network), profileStorageContractAddress.Address); var profileFunction = profileStorageContract.GetFunction("profile"); var currentIdentities = await OTIdentity.GetAll(connection, blockchainID); Dictionary <string, decimal> paidOutBalances = (await connection .QueryAsync <PayoutGroupHolder>( @"SELECT Holder, SUM(Amount) Amount FROM OTContract_Holding_Paidout WHERE BlockchainID = @blockchainID GROUP BY Holder", new { blockchainID = blockchainID })) .ToDictionary(k => k.Holder, k => k.Amount); Dictionary <string, OfferGroupHolder> offerTotals = (await connection.QueryAsync <OfferGroupHolder>( @"select i.Identity, COUNT(o.OfferID) as OffersTotal, (SELECT count(so.OfferID) FROM otoffer_holders sh join otoffer so on so.OfferID = sh.OfferID AND so.BlockchainID = sh.BlockchainID WHERE sh.blockchainid = @blockchainID and sh.Holder = i.Identity AND so.CreatedTimestamp >= Date_Add(NOW(), INTERVAL -7 DAY)) as OffersLast7Days from otidentity i join otoffer_holders h on h.Holder = i.Identity AND h.BlockchainID = i.BlockchainID join otoffer o on o.OfferID = h.OfferID AND o.BlockchainID = h.BlockchainID WHERE i.blockchainid = @blockchainID GROUP BY i.Identity", new { blockchainID })).ToDictionary(k => k.Identity, k => k); // NodeManagementWallet[] managementWallets = (await connection.QueryAsync<NodeManagementWallet>( // @"SELECT I.Identity, PC.ManagementWallet as CreateWallet, IT.ManagementWallet TransferWallet FROM OTIdentity I //LEFT JOIN OTContract_Profile_ProfileCreated PC ON PC.Profile = I.Identity AND PC.BlockchainID = I.BlockchainID //LEFT JOIN OTContract_Profile_IdentityTransferred IT ON IT.NewIdentity = I.Identity AND IT.BlockchainID = I.BlockchainID //WHERE I.Version > 0 AND I.BlockchainID = @blockchainID", new // { // blockchainID // })).ToArray(); foreach (OTIdentity currentIdentity in currentIdentities) { bool updateProfile = true; DateTime?lastActivityDate = null; if (currentIdentity.Version != Constants.CurrentERCVersion) { if (currentIdentity.LastSyncedTimestamp.HasValue) { DateTime adjustedNowTime = DateTime.Now; if ((adjustedNowTime - currentIdentity.LastSyncedTimestamp.Value).TotalDays <= 14) { updateProfile = false; } } } else if (currentIdentity.LastSyncedTimestamp.HasValue) { var dates = (await connection.QueryAsync <DateTime?>(@" select MAX(Timestamp) from otcontract_profile_identitycreated r join ethblock b on r.BlockNumber = b.BlockNumber AND r.BlockchainID = b.BlockchainID WHERE r.NewIdentity = @identity AND r.blockchainID = @blockchainID union select MAX(Timestamp) from otcontract_profile_identitytransferred r join ethblock b on r.BlockNumber = b.BlockNumber AND r.BlockchainID = b.BlockchainID WHERE r.NewIdentity = @identity AND r.blockchainID = @blockchainID union select MAX(Timestamp) from otcontract_profile_profilecreated r join ethblock b on r.BlockNumber = b.BlockNumber AND r.BlockchainID = b.BlockchainID WHERE r.Profile = @identity AND r.blockchainID = @blockchainID union select MAX(Timestamp) from otcontract_profile_tokensdeposited r join ethblock b on r.BlockNumber = b.BlockNumber AND r.BlockchainID = b.BlockchainID WHERE r.Profile = @identity AND r.blockchainID = @blockchainID union select MAX(Timestamp) from otcontract_profile_tokensreleased r join ethblock b on r.BlockNumber = b.BlockNumber AND r.BlockchainID = b.BlockchainID WHERE r.Profile = @identity AND r.blockchainID = @blockchainID union select MAX(Timestamp) from otcontract_profile_tokensreserved r join ethblock b on r.BlockNumber = b.BlockNumber AND r.BlockchainID = b.BlockchainID WHERE r.Profile = @identity AND r.blockchainID = @blockchainID union select MAX(Timestamp) from otcontract_profile_tokenstransferred r join ethblock b on r.BlockNumber = b.BlockNumber AND r.BlockchainID = b.BlockchainID WHERE (r.Sender = @identity OR r.Receiver = @identity) AND r.blockchainID = @blockchainID union select MAX(Timestamp) from otcontract_profile_tokenswithdrawn r join ethblock b on r.BlockNumber = b.BlockNumber AND r.BlockchainID = b.BlockchainID WHERE r.Profile = @identity AND r.blockchainID = @blockchainID union select MAX(b.Timestamp) from otoffer_holders h join otoffer o on o.offerid = h.offerid and o.BlockchainID = h.BlockchainID join ethblock b on b.blocknumber = o.finalizedblocknumber AND h.BlockchainID = b.BlockchainID where h.Holder = @identity AND h.blockchainID = @blockchainID union SELECT MAX(Timestamp) FROM otcontract_litigation_litigationcompleted lc WHERE lc.HolderIdentity = @identity AND lc.DHWasPenalized = 1 AND lc.blockchainID = @blockchainID union select MAX(b.Timestamp) from otcontract_holding_paidout p join ethblock b on b.blocknumber = p.blocknumber and b.BlockchainID = p.BlockchainID where p.holder = @identity AND p.blockchainID = @blockchainID union select MAX(b.Timestamp) from otcontract_holding_offerfinalized of join otcontract_holding_offercreated oc on oc.OfferId = of.OfferId and oc.BlockchainID = of.BlockchainID join OTIdentity i on i.NodeId = oc.DCNodeId and i.BlockchainID = oc.BlockchainID join ethblock b on of.BlockNumber = b.BlockNumber and b.BlockchainID = of.BlockchainID where i.Identity = @identity AND of.blockchainID = @blockchainID", new { identity = currentIdentity.Identity, blockchainID })).ToArray().Where(d => d.HasValue).Select(d => d.Value).ToArray(); var adjustedNowTime = DateTime.Now; if (dates.Any()) { lastActivityDate = dates.Max(); if (lastActivityDate.Value <= currentIdentity.LastSyncedTimestamp) { if ((adjustedNowTime - currentIdentity.LastSyncedTimestamp.Value).TotalHours <= 16) { updateProfile = false; } } } else { if ((adjustedNowTime - currentIdentity.LastSyncedTimestamp.Value).TotalHours <= 24) { updateProfile = false; } } } if (updateProfile || (currentIdentity.NodeId ?? "").Length > 40) { var output = await profileFunction.CallDeserializingToObjectAsync <ProfileFunctionOutput>( currentIdentity.Identity); var stake = Web3.Convert.FromWei(output.stake); var stakeReserved = Web3.Convert.FromWei(output.stakeReserved); var nodeId = HexHelper.ByteArrayToString(output.nodeId, false).Substring(0, 40); var withdrawalAmount = Web3.Convert.FromWei(output.withdrawalAmount); var withdrawalTimestamp = (UInt64)output.withdrawalTimestamp; var reputation = (UInt64)output.reputation; if (currentIdentity.Stake != stake || currentIdentity.StakeReserved != stakeReserved || currentIdentity.NodeId != nodeId || currentIdentity.WithdrawalAmount != withdrawalAmount || currentIdentity.WithdrawalPending != output.withdrawalPending || currentIdentity.WithdrawalTimestamp != withdrawalTimestamp || currentIdentity.Reputation != reputation) { currentIdentity.Stake = stake; currentIdentity.StakeReserved = stakeReserved; currentIdentity.NodeId = nodeId; currentIdentity.WithdrawalAmount = withdrawalAmount; currentIdentity.WithdrawalPending = output.withdrawalPending; currentIdentity.WithdrawalTimestamp = withdrawalTimestamp; currentIdentity.Reputation = reputation; currentIdentity.LastSyncedTimestamp = DateTime.Now; await OTIdentity.UpdateFromProfileFunction(connection, currentIdentity); } else { currentIdentity.LastSyncedTimestamp = DateTime.Now; await OTIdentity.UpdateLastSyncedTimestamp(connection, currentIdentity); } } if (!paidOutBalances.TryGetValue(currentIdentity.Identity, out var paidRow)) { paidRow = 0; } offerTotals.TryGetValue(currentIdentity.Identity, out var offerRow); if (currentIdentity.Paidout != paidRow || currentIdentity.TotalOffers != (offerRow?.OffersTotal ?? 0) || currentIdentity.OffersLast7Days != (offerRow?.OffersLast7Days ?? 0) || currentIdentity.ActiveOffers != 0 || (currentIdentity.LastActivityTimestamp != lastActivityDate && lastActivityDate.HasValue)) { currentIdentity.Paidout = paidRow; currentIdentity.TotalOffers = offerRow?.OffersTotal ?? 0; currentIdentity.OffersLast7Days = offerRow?.OffersLast7Days ?? 0; currentIdentity.ActiveOffers = 0; currentIdentity.LastActivityTimestamp = lastActivityDate; await OTIdentity.UpdateFromPaidoutAndApprovedCalculation(connection, currentIdentity); } } } return(true); }
public static string GetContractAbi(ContractTypeEnum ContractTypeEnum, BlockchainType type, BlockchainNetwork network) { string path = $"OTHub.Settings.Abis.{type}.{network}."; switch (ContractTypeEnum) { case ContractTypeEnum.Approval: path += "approval.json"; break; case ContractTypeEnum.Holding: path += "holding.json"; break; case ContractTypeEnum.HoldingStorage: path += "holding-storage.json"; break; case ContractTypeEnum.Profile: path += "profile.json"; break; case ContractTypeEnum.ProfileStorage: path += "profile-storage.json"; break; case ContractTypeEnum.Replacement: path += "replacement.json"; break; case ContractTypeEnum.Litigation: path += "litigation.json"; break; case ContractTypeEnum.LitigationStorage: path += "litigation-storage.json"; break; case ContractTypeEnum.Token: path += "token.json"; break; case ContractTypeEnum.ERC725: path += "erc725.json"; break; case ContractTypeEnum.Reading: path += "reading.json"; break; case ContractTypeEnum.Hub: path += "hub.json"; break; case ContractTypeEnum.StarfleetStake: path += "starfleetstake.json"; break; case ContractTypeEnum.StarfleetBounty: path += "bounty.json"; break; default: throw new Exception("Not supported: " + ContractTypeEnum); } using (Stream resource = Assembly.GetExecutingAssembly().GetManifestResourceStream(path)) using (StreamReader reader = new StreamReader(resource)) { return(reader.ReadToEnd()); } }
public override async Task <bool> Execute(Source source, BlockchainType blockchain, BlockchainNetwork network) { await using (var connection = new MySqlConnection(OTHubSettings.Instance.MariaDB.ConnectionString)) { int blockchainID = await GetBlockchainID(connection, blockchain, network); var pendingJobs = (await connection.QueryAsync( @"SELECT * FROM findnodesbywalletjob WHERE EndDate is null AND BlockchainID = @blockchainID ORDER BY StartDate", new { blockchainID })).ToArray(); foreach (var pendingJob in pendingJobs) { OTIdentity[] identities = await OTIdentity.GetAll(connection, blockchainID); uint id = pendingJob.ID; string address = pendingJob.Address; string userID = pendingJob.UserID; Logger.WriteLine(source, "Finding wallets for address " + address + " and user id " + userID + " on blockchain " + blockchain); try { await ProcessJob(connection, blockchainID, identities, address, blockchain, network, source, id); } catch (Exception ex) { Logger.WriteLine(source, ex.ToString()); await connection.ExecuteAsync(@"UPDATE findnodesbywalletjob SET Failed = 1, EndDate = @endDate WHERE ID = @id", new { id = id, endDate = DateTime.UtcNow }); return(false); } } } return(true); }
private static async Task <bool> Run(int blockchainID, string webSocketsUrl, string rpcUrl, BlockchainType blockchainType, BlockchainNetwork blockchainNetwork) { bool hasFailed = false; using (var client = new StreamingWebSocketClient(webSocketsUrl)) { EthLogsObservableSubscription logsSubscription = new EthLogsObservableSubscription(client); Web3 cl = new Web3(rpcUrl); RequestInterceptor r = new RPCInterceptor(blockchainType); cl.Client.OverridingRequestInterceptor = r; EthApiService eth = new EthApiService(cl.Client); logsSubscription.GetSubscriptionDataResponsesAsObservable().Subscribe(async filterLog => { FilterLog transaction = filterLog; if (transaction.Removed) { return; } if (SmartContractManager.TryGetAddress(blockchainID, filterLog.Address, out ContractTypeEnum type)) { await ProcessSmartContractEvent(blockchainID, blockchainType, blockchainNetwork, type, eth, filterLog, transaction, cl); } }); _dictionary[blockchainID] = new Subscription(client, logsSubscription); await client.StartAsync(); client.Error += Client_Error; while (!client.IsStarted) { await Task.Delay(1000); } await logsSubscription.SubscribeAsync(); while (!hasFailed) { try { var handler = new EthBlockNumberObservableHandler(client); handler.GetResponseAsObservable().Subscribe(integer => { }); await handler.SendRequestAsync(); SystemStatus status = new SystemStatus(TaskNames.WebSockets, blockchainID); await using (var connection = new MySqlConnection(OTHubSettings.Instance.MariaDB.ConnectionString)) { await status.InsertOrUpdate(connection, true, null, false, "Blockchain Sync"); } } catch (Exception ex) when(errorCounter <= 100) { hasFailed = true; _dictionary.Remove(blockchainID, out _); client.Dispose(); //try //{ // await client.StopAsync(); // await client.StartAsync(); //} //catch (Exception) //{ // Logger.WriteLine(Source.BlockchainSync, ex.ToString()); //} } await Task.Delay(120000); } } return(!hasFailed); }
public override async Task <bool> Execute(Source source, BlockchainType blockchain, BlockchainNetwork network) { await using (var connection = new MySqlConnection(OTHubSettings.Instance.MariaDB.ConnectionString)) { int blockchainID = await GetBlockchainID(connection, blockchain, network); await OTOfferHolder.UpdateLitigationForAllOffers(connection, blockchainID); } return(true); }
public override async Task <bool> Execute(Source source, BlockchainType blockchain, BlockchainNetwork network) { ClientBase.ConnectionTimeout = new TimeSpan(0, 0, 5, 0); await using (var connection = new MySqlConnection(OTHubSettings.Instance.MariaDB.ConnectionString)) { int blockchainID = await GetBlockchainID(connection, blockchain, network); var cl = await GetWeb3(connection, blockchainID, blockchain); var eth = new EthApiService(cl.Client); foreach (var contract in await OTContract.GetByTypeAndBlockchain(connection, (int)ContractTypeEnum.Profile, blockchainID)) { if (contract.IsArchived && contract.LastSyncedTimestamp.HasValue && (DateTime.Now - contract.LastSyncedTimestamp.Value).TotalDays <= 5) { #if DEBUG Logger.WriteLine(source, " Skipping contract: " + contract.Address); #endif continue; } Logger.WriteLine(source, " Using contract: " + contract.Address); string abi = AbiHelper.GetContractAbi(ContractTypeEnum.Profile, blockchain, network); var profileContract = new Contract(eth, abi, contract.Address); var profileCreatedEvent = profileContract.GetEvent("ProfileCreated"); var identityCreatedEvent = profileContract.GetEvent("IdentityCreated"); var identityTransferredEvent = profileContract.GetEvent("IdentityTransferred"); var tokensDepositedEvent = profileContract.GetEvent("TokensDeposited"); var tokensReleasedEvent = profileContract.GetEvent("TokensReleased"); var tokensWithdrawnEvent = profileContract.GetEvent("TokensWithdrawn"); var tokensTransferredEvent = profileContract.GetEvent("TokensTransferred"); var tokensReservedEvent = profileContract.GetEvent("TokensReserved"); Function createProfileFunction = profileContract.GetFunction("createProfile"); Function transferProfileFunction = profileContract.GetFunction("transferProfile"); ulong size = (ulong)10000; BlockBatcher batcher = BlockBatcher.Start(contract.SyncBlockNumber, (ulong)LatestBlockNumber.Value, size, async delegate(ulong start, ulong end) { await Sync(connection, profileCreatedEvent, identityCreatedEvent, identityTransferredEvent, tokensDepositedEvent, tokensReleasedEvent, tokensWithdrawnEvent, tokensTransferredEvent, tokensReservedEvent, contract, source, createProfileFunction, transferProfileFunction, start, end, blockchainID, cl); }); await batcher.Execute(); } await CreateMissingIdentities(connection, cl, blockchainID, blockchain, network); } return(true); }
private static async Task ProcessHoldingSmartContractEvent(int blockchainID, BlockchainType blockchainType, BlockchainNetwork blockchainNetwork, EthApiService eth, FilterLog filterLog, FilterLog transaction, Web3 cl) { var contract = new Contract(eth, AbiHelper.GetContractAbi(ContractTypeEnum.Holding, blockchainType, blockchainNetwork), filterLog.Address); var offerCreatedEvent = contract.GetEvent("OfferCreated"); var offerFinalizedEvent = contract.GetEvent("OfferFinalized"); var offerTaskEvent = contract.GetEvent("OfferTask"); var paidOutEvent = contract.GetEvent("PaidOut"); await using (var connection = new MySqlConnection(OTHubSettings.Instance.MariaDB.ConnectionString)) { try { if (offerCreatedEvent.IsLogForEvent(transaction)) { var events = offerCreatedEvent.DecodeAllEventsForEvent <Models.Program.OfferCreated>( new[] { filterLog }); foreach (EventLog <Models.Program.OfferCreated> eventLog in events) { await SyncHoldingContractTask.ProcessOfferCreated(connection, blockchainID, cl, filterLog.Address, eventLog); } await ProcessJobsTask.Execute(connection, blockchainID, blockchainType, blockchainNetwork); } if (offerFinalizedEvent.IsLogForEvent(transaction)) { var events = offerFinalizedEvent.DecodeAllEventsDefaultForEvent(new[] { filterLog }); foreach (EventLog <List <ParameterOutput> > eventLog in events) { await SyncHoldingContractTask.ProcessOfferFinalised(connection, blockchainID, cl, filterLog.Address, eventLog); } await ProcessJobsTask.Execute(connection, blockchainID, blockchainType, blockchainNetwork); } if (paidOutEvent.IsLogForEvent(transaction)) { var events = paidOutEvent.DecodeAllEventsDefaultForEvent(new[] { filterLog }); foreach (EventLog <List <ParameterOutput> > eventLog in events) { await SyncHoldingContractTask.ProcessPayout(connection, blockchainID, cl, filterLog.Address, eventLog); } } } catch (Exception ex) { Logger.WriteLine(Source.BlockchainSync, ex.ToString()); } } }
public override async Task <bool> Execute(Source source, BlockchainType blockchain, BlockchainNetwork network) { ClientBase.ConnectionTimeout = new TimeSpan(0, 0, 5, 0); await using (var connection = new MySqlConnection(OTHubSettings.Instance.MariaDB.ConnectionString)) { int blockchainID = await GetBlockchainID(connection, blockchain, network); var cl = await GetWeb3(connection, blockchainID, blockchain); var eth = new EthApiService(cl.Client); foreach (var contract in await OTContract.GetByTypeAndBlockchain(connection, (int)ContractTypeEnum.Holding, blockchainID)) { if (contract.IsArchived && contract.LastSyncedTimestamp.HasValue && (DateTime.Now - contract.LastSyncedTimestamp.Value).TotalDays <= 5) { #if DEBUG Logger.WriteLine(source, " Skipping contract: " + contract.Address); #endif continue; } Logger.WriteLine(source, " Using contract: " + contract.Address); var holdingContract = new Contract(eth, AbiHelper.GetContractAbi(ContractTypeEnum.Holding, blockchain, network), contract.Address); var offerCreatedEvent = holdingContract.GetEvent("OfferCreated"); var offerFinalizedEvent = holdingContract.GetEvent("OfferFinalized"); var paidOutEvent = holdingContract.GetEvent("PaidOut"); var ownershipTransferredEvent = holdingContract.GetEvent("OwnershipTransferred"); var offerTaskEvent = holdingContract.GetEvent("OfferTask"); ulong size = (ulong)10000; BlockBatcher batcher = BlockBatcher.Start(contract.SyncBlockNumber, (ulong)LatestBlockNumber.Value, size, async delegate(ulong start, ulong end) { await Sync(connection, contract, offerCreatedEvent, offerFinalizedEvent, paidOutEvent, ownershipTransferredEvent, offerTaskEvent, source, start, end, blockchainID, cl); }); await batcher.Execute(); } } return(true); }