コード例 #1
0
        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
        }
コード例 #2
0
        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));
            }
        }
コード例 #3
0
        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));
            }
        }
コード例 #4
0
ファイル: TaskController.cs プロジェクト: lukeskinner/OTHub
            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);
            }
コード例 #5
0
        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);
            }
        }
コード例 #6
0
ファイル: Blockchain.cs プロジェクト: BusinessChain/BToken
        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);
        }
コード例 #7
0
ファイル: TaskController.cs プロジェクト: lukeskinner/OTHub
        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());
            }
        }
コード例 #8
0
        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));
            }
        }
コード例 #9
0
ファイル: ProcessJobsTask.cs プロジェクト: lukeskinner/OTHub
        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
                    }));
                }
            }
        }
コード例 #10
0
        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);
        }
コード例 #11
0
        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
                });
            }
        }
コード例 #12
0
        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);
        }
コード例 #13
0
ファイル: ToolsTask.cs プロジェクト: lukeskinner/OTHub
        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
            });
        }
コード例 #14
0
        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
                });
            }
        }
コード例 #15
0
        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());
                }
            }
        }
コード例 #16
0
        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());
                }
            }
        }
コード例 #17
0
        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);
        }
コード例 #18
0
        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);
        }
コード例 #19
0
        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);
        }
コード例 #20
0
ファイル: AbiHelper.cs プロジェクト: lukeskinner/OTHub
        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());
                }
        }
コード例 #21
0
ファイル: ToolsTask.cs プロジェクト: lukeskinner/OTHub
        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);
        }
コード例 #22
0
        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);
        }
コード例 #23
0
        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);
        }
コード例 #24
0
        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);
        }
コード例 #25
0
        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());
                }
            }
        }
コード例 #26
0
        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);
        }