示例#1
0
        public Contract(EthApiService eth, Type[] contractMessagesTypes, string contractAddress)
        {
            Eth = eth;
            var abiExtractor = new AttributesToABIExtractor();

            ContractBuilder = new ContractBuilder(contractMessagesTypes, contractAddress);
            DefaultBlock    = eth.DefaultBlock;
        }
示例#2
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
                });
            }
        }
示例#3
0
 public Contract(EthApiService eth, string abi, string contractAddress)
 {
     Eth             = eth;
     ContractBuilder = new ContractBuilder(abi, contractAddress);
     if (eth != null)
     {
         DefaultBlock = eth.DefaultBlock;
     }
 }
示例#4
0
 public Contract(EthApiService eth, Type[] contractMessagesTypes, string contractAddress)
 {
     Eth             = eth;
     ContractBuilder = new ContractBuilder(contractMessagesTypes, contractAddress);
     if (eth != null)
     {
         DefaultBlock = eth.DefaultBlock;
     }
 }
        public async Task Connect()
        {
            var           api = new EthApiService(_client0);
            HexBigInteger hex = await api.Blocks.GetBlockNumber.SendRequestAsync();

            long count = (long)(BigInteger)hex;

            Debug.WriteLine(count);
            count.Should().BeGreaterThan(1);
        }
        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.Litigation, 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.Litigation, blockchain, network), contract.Address);

                    var litigationInitiatedEvent = holdingContract.GetEvent("LitigationInitiated");
                    var litigationAnsweredEvent  = holdingContract.GetEvent("LitigationAnswered");
                    var litigationTimedOutEvent  = holdingContract.GetEvent("LitigationTimedOut");
                    var litigationCompletedEvent = holdingContract.GetEvent("LitigationCompleted");
                    var replacementStartedEvent  = holdingContract.GetEvent("ReplacementStarted");

                    ulong size = (ulong)10000;

                    BlockBatcher batcher = BlockBatcher.Start(contract.SyncBlockNumber, (ulong)LatestBlockNumber.Value, size,
                                                              async delegate(ulong start, ulong end)
                    {
                        await Sync(connection, litigationInitiatedEvent, litigationAnsweredEvent,
                                   litigationTimedOutEvent,
                                   litigationCompletedEvent,
                                   replacementStartedEvent,
                                   contract, source, start,
                                   end, blockchainID, cl);
                    });

                    await batcher.Execute();
                }
            }

            return(true);
        }
示例#7
0
 public Contract(EthApiService eth, string abi, string contractAddress)
 {
     Eth         = eth;
     ContractABI = new ABIDeserialiser().DeserialiseContract(abi);
     Address     = contractAddress;
 }
示例#8
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);
        }
示例#9
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
                });
            }
        }
示例#10
0
        public static async Task ProcessIdentityCreated(MySqlConnection connection, string contractAddress, int blockchainID,
                                                        Web3 cl, EventLog <List <ParameterOutput> > eventLog, EthApiService eth)
        {
            using (await LockManager.GetLock(LockType.IdentityCreated).Lock())
            {
                var newIdentity = (string)eventLog.Event
                                  .FirstOrDefault(p => p.Parameter.Name == "newIdentity").Result;

                if (OTContract_Profile_IdentityCreated.Exists(connection, newIdentity, blockchainID))
                {
                    return;
                }

                var block = await BlockHelper.GetBlock(connection, eventLog.Log.BlockHash, eventLog.Log.BlockNumber,
                                                       cl, blockchainID);

                var profile = (string)eventLog.Event
                              .FirstOrDefault(p => p.Parameter.Name == "profile").Result;



                var transaction = eth.Transactions.GetTransactionByHash.SendRequestAsync(eventLog.Log.TransactionHash);

                var receipt = eth.Transactions.GetTransactionReceipt.SendRequestAsync(eventLog.Log.TransactionHash);

                await transaction;
                await receipt;

                var row = new OTContract_Profile_IdentityCreated
                {
                    TransactionHash = eventLog.Log.TransactionHash,
                    ContractAddress = contractAddress,
                    Profile         = profile,
                    NewIdentity     = newIdentity,
                    BlockNumber     = (UInt64)eventLog.Log.BlockNumber.Value,
                    GasUsed         = (UInt64)receipt.Result.GasUsed.Value,
                    GasPrice        = (UInt64)transaction.Result.GasPrice.Value,
                    BlockchainID    = blockchainID
                };

                OTContract_Profile_IdentityCreated.InsertOrUpdate(connection, row);
            }
        }
示例#11
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());
                }
            }
        }
示例#12
0
        public async Task <PossiblePayoutModel[]> GetPossibleJobPayouts([FromQuery] bool includeActiveJobs, [FromQuery] bool includeCompletedJobs,
                                                                        [FromQuery] int blockchainID, [FromQuery] DateTime?dateFrom, [FromQuery] DateTime?dateTo)
        {
            await using (MySqlConnection connection =
                             new MySqlConnection(OTHubSettings.Instance.MariaDB.ConnectionString))
            {
                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 latestBlockParam = BlockParameter.CreateLatest();

                var block = await cl.Eth.Blocks.GetBlockWithTransactionsByNumber.SendRequestAsync(latestBlockParam);

                var rows = (await connection.QueryAsync <PossiblePayoutModel>(@"WITH CTEJobs AS (
SELECT 
b.ID BlockchainID, b.DisplayName BlockchainName, o.OfferID, MN.NodeID, i.Identity, o.TokenAmountPerHolder TokenAmount,
DATE_Add(o.FinalizedTimeStamp, INTERVAL + o.HoldingTimeInMinutes MINUTE) as JobEndTimestamp, of.Timestamp FinalizedTimestamp,
o.TokenAmountPerHolder * 1000000000000000000 TokenAmountInWei, o.HoldingTimeInMinutes
FROM
mynodes MN
JOIN otidentity i ON i.NodeId = MN.NodeID
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
JOIN blockchains b ON b.id = o.BlockchainID
JOIN otcontract_holding_offerfinalized of ON of.OfferID = o.OfferID AND of.BlockchainID = o.BlockchainID
WHERE o.IsFinalized = 1 AND MN.UserID = @userID AND (@blockchainID IS NULL OR i.BlockchainID = @blockchainID)
AND ((@includeActiveJobs = 1 AND DATE_Add(o.FinalizedTimeStamp, INTERVAL + o.HoldingTimeInMinutes MINUTE) >= NOW())
OR (@includeCompletedJobs = 1 AND DATE_Add(o.FinalizedTimeStamp, INTERVAL + o.HoldingTimeInMinutes MINUTE) <= NOW()))
AND (@dateFrom IS NULL OR DATE_Add(o.FinalizedTimeStamp, INTERVAL + o.HoldingTimeInMinutes MINUTE) >= @dateFrom)
AND (@dateTo IS NULL OR DATE_Add(o.FinalizedTimeStamp, INTERVAL + o.HoldingTimeInMinutes MINUTE) <= @dateTo)
),

CTEPayouts AS (
SELECT MN.NodeID, po.OfferID, SUM(po.Amount) PaidAmount, COUNT(po.OfferId) PayoutCount, MAX(po.Timestamp) LastPayout
FROM otcontract_holding_paidout po
JOIN otidentity i ON i.Identity = po.Holder AND i.BlockchainID = po.BlockchainID
JOIN mynodes MN ON MN.NodeID = i.NodeId
WHERE MN.UserID = @userID AND (@blockchainID IS NULL OR po.BlockchainID = @blockchainID)
GROUP BY MN.NodeID, po.OfferID
)

SELECT 
J.BlockchainID, J.BlockchainName, J.OfferID, J.NodeID, J.Identity, J.TokenAmount, COALESCE(P.PaidAmount, 0) PaidAmount, 
COALESCE(P.PayoutCount, 0) PayoutCount, P.LastPayout, J.JobEndTimestamp,
((J.TokenAmountInWei * (LEAST(UNIX_TIMESTAMP(J.JobEndTimestamp), @currentBlockUnixTimestamp) - UNIX_TIMESTAMP(GREATEST(COALESCE(P.LastPayout, 0), J.FinalizedTimestamp)))) / (J.HoldingTimeInMinutes * 60)) / 1000000000000000000 EstimatedPayout
FROM CTEJobs J
LEFT JOIN CTEPayouts P ON P.OfferID = J.OfferID
WHERE J.TokenAmount != COALESCE(P.PaidAmount, 0)", new
                {
                    userID = User.Identity.Name,
                    includeActiveJobs = includeActiveJobs,
                    includeCompletedJobs = includeCompletedJobs,
                    blockchainID = blockchainID,
                    dateFrom = dateFrom,
                    dateTo = dateTo,
                    currentBlockUnixTimestamp = (ulong)block.Timestamp.Value
                })).ToArray();

                return(rows);
            }
        }
示例#13
0
 public Contract(EthApiService eth, string abi, string contractAddress)
 {
     Eth             = eth;
     ContractBuilder = new ContractBuilder(abi, contractAddress);
 }
示例#14
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);
        }
        public static async Task ProcessLitigationInitiated(MySqlConnection connection, int blockchainID, Web3 cl,
                                                            EventLog <List <ParameterOutput> > eventLog, EthApiService eth)
        {
            if (OTContract_Litigation_LitigationInitiated.TransactionExists(connection, eventLog.Log.TransactionHash, blockchainID))
            {
                return;
            }

            var block = await BlockHelper.GetBlock(connection, eventLog.Log.BlockHash, eventLog.Log.BlockNumber,
                                                   cl, blockchainID);

            var offerId =
                HexHelper.ByteArrayToString((byte[])eventLog.Event
                                            .First(e => e.Parameter.Name == "offerId").Result);

            var holderIdentity = (string)eventLog.Event
                                 .First(e => e.Parameter.Name == "holderIdentity").Result;

            var requestedObjectIndex = (BigInteger)eventLog.Event
                                       .First(e => e.Parameter.Name == "requestedObjectIndex").Result;


            var requestedBlockIndex = (BigInteger)eventLog.Event
                                      .First(e => e.Parameter.Name == "requestedBlockIndex").Result;

            var transaction = await eth.Transactions.GetTransactionByHash.SendRequestAsync(eventLog.Log.TransactionHash);

            var receipt = await eth.Transactions.GetTransactionReceipt.SendRequestAsync(eventLog.Log.TransactionHash);

            var row = new OTContract_Litigation_LitigationInitiated
            {
                TransactionHash      = eventLog.Log.TransactionHash,
                BlockNumber          = (UInt64)eventLog.Log.BlockNumber.Value,
                Timestamp            = block.Timestamp,
                OfferId              = offerId,
                RequestedObjectIndex = (UInt64)requestedObjectIndex,
                RequestedBlockIndex  = (UInt64)requestedBlockIndex,
                HolderIdentity       = holderIdentity,
                GasPrice             = (UInt64)transaction.GasPrice.Value,
                GasUsed              = (UInt64)receipt.GasUsed.Value,
                BlockchainID         = blockchainID
            };

            await OTContract_Litigation_LitigationInitiated.InsertIfNotExist(connection, row);
        }
        private async Task Sync(MySqlConnection connection, OTContract contract, Event offerCreatedEvent,
                                Event offerFinalizedEvent, Event paidOutEvent, Event ownershipTransferredEvent, Event offerTaskEvent,
                                Source source, ulong start, ulong end, int blockchainID, Web3 cl)
        {
            Logger.WriteLine(source, "Syncing holding " + start + " to " + end);

            var toBlock = new BlockParameter(end);


            var createEvents = await offerCreatedEvent.GetAllChanges <Models.Program.OfferCreated>(
                offerCreatedEvent.CreateFilterInput(new BlockParameter(start),
                                                    toBlock));


            var finalizedEvents = await offerFinalizedEvent.GetAllChangesDefault(
                offerFinalizedEvent.CreateFilterInput(new BlockParameter(start),
                                                      toBlock));



            var payoutEvents = await paidOutEvent.GetAllChangesDefault(
                paidOutEvent.CreateFilterInput(new BlockParameter(start), toBlock));



            var ownershipTransferredEvents = await ownershipTransferredEvent.GetAllChangesDefault(
                ownershipTransferredEvent.CreateFilterInput(new BlockParameter(start),
                                                            toBlock));


            var offerTaskEvents = await offerTaskEvent.GetAllChangesDefault(
                offerTaskEvent.CreateFilterInput(new BlockParameter(start), toBlock));


            if (createEvents.Any())
            {
                Logger.WriteLine(source, "Found " + createEvents.Count + " offer created events");
            }


            if (finalizedEvents.Any())
            {
                Logger.WriteLine(source, "Found " + finalizedEvents.Count + " offer finalized events");
            }


            if (payoutEvents.Any())
            {
                Logger.WriteLine(source, "Found " + payoutEvents.Count + " offer payout events");
            }


            if (ownershipTransferredEvents.Any())
            {
                Logger.WriteLine(source, "Found " + ownershipTransferredEvents.Count + " ownership transferred events");
            }


            if (offerTaskEvents.Any())
            {
                Logger.WriteLine(source, "Found " + offerTaskEvents.Count + " offer task events");
            }

            foreach (EventLog <Models.Program.OfferCreated> eventLog in createEvents)
            {
                await ProcessOfferCreated(connection, blockchainID, cl, contract.Address, eventLog);
            }

            foreach (EventLog <List <ParameterOutput> > eventLog in finalizedEvents)
            {
                await ProcessOfferFinalised(connection, blockchainID, cl, contract.Address, eventLog);
            }

            foreach (EventLog <List <ParameterOutput> > eventLog in payoutEvents)
            {
                await ProcessPayout(connection, blockchainID, cl, contract.Address, eventLog);
            }

            var eth = new EthApiService(cl.Client);

            foreach (EventLog <List <ParameterOutput> > eventLog in ownershipTransferredEvents)
            {
                var block = await BlockHelper.GetBlock(connection, eventLog.Log.BlockHash, eventLog.Log.BlockNumber,
                                                       cl, blockchainID);

                var previousOwner = (string)eventLog.Event
                                    .FirstOrDefault(e => e.Parameter.Name == "previousOwner").Result;
                var newOwner = (string)eventLog.Event.FirstOrDefault(e => e.Parameter.Name == "newOwner")
                               .Result;

                var transaction = eth.Transactions.GetTransactionByHash.SendRequestAsync(eventLog.Log.TransactionHash);

                var receipt = eth.Transactions.GetTransactionReceipt.SendRequestAsync(eventLog.Log.TransactionHash);

                await transaction;
                await receipt;

                OTContract_Holding_OwnershipTransferred.InsertIfNotExist(connection,
                                                                         new OTContract_Holding_OwnershipTransferred
                {
                    TransactionHash = eventLog.Log.TransactionHash,
                    BlockNumber     = (UInt64)eventLog.Log.BlockNumber.Value,
                    ContractAddress = contract.Address,
                    NewOwner        = newOwner,
                    PreviousOwner   = previousOwner,
                    GasPrice        = (UInt64)transaction.Result.GasPrice.Value,
                    GasUsed         = (UInt64)receipt.Result.GasUsed.Value,
                    BlockchainID    = blockchainID
                });
            }

            foreach (EventLog <List <ParameterOutput> > eventLog in offerTaskEvents)
            {
                await ProcessOfferTasks(connection, blockchainID, cl, contract.Address, eventLog, eth);
            }

            contract.LastSyncedTimestamp = DateTime.Now;
            contract.SyncBlockNumber     = end;

            await OTContract.Update(connection, contract, false, false);
        }
示例#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);
        }
        public static async Task ProcessOfferTasks(MySqlConnection connection, int blockchainID, Web3 cl,
                                                   string contractAddress, EventLog <List <ParameterOutput> > eventLog, EthApiService eth)
        {
            using (await LockManager.GetLock(LockType.OfferTask).Lock())
            {
                var offerId =
                    HexHelper.ByteArrayToString((byte[])eventLog.Event
                                                .First(e => e.Parameter.Name == "offerId").Result);

                if (OTContract_Holding_OfferTask.Exists(connection, offerId, blockchainID))
                {
                    return;
                }

                var block = await BlockHelper.GetBlock(connection, eventLog.Log.BlockHash, eventLog.Log.BlockNumber,
                                                       cl, blockchainID);

                var dataSetId =
                    HexHelper.ByteArrayToString((byte[])eventLog.Event
                                                .First(e => e.Parameter.Name == "dataSetId").Result);
                var dcNodeId =
                    HexHelper.ByteArrayToString((byte[])eventLog.Event
                                                .First(e => e.Parameter.Name == "dcNodeId").Result);

                var task = HexHelper.ByteArrayToString(
                    (byte[])eventLog.Event.First(e => e.Parameter.Name == "task").Result);

                var transaction = eth.Transactions.GetTransactionByHash.SendRequestAsync(eventLog.Log.TransactionHash);

                var receipt = eth.Transactions.GetTransactionReceipt.SendRequestAsync(eventLog.Log.TransactionHash);

                await transaction;
                await receipt;

                OTContract_Holding_OfferTask.InsertIfNotExist(connection, new OTContract_Holding_OfferTask
                {
                    BlockNumber     = (UInt64)eventLog.Log.BlockNumber.Value,
                    Task            = task,
                    TransactionHash = eventLog.Log.TransactionHash,
                    ContractAddress = contractAddress,
                    DCNodeId        = dcNodeId,
                    DataSetId       = dataSetId,
                    OfferId         = offerId,
                    GasPrice        = (UInt64)transaction.Result.GasPrice.Value,
                    GasUsed         = (UInt64)receipt.Result.GasUsed.Value,
                    BlockchainID    = blockchainID
                });
            }
        }
示例#19
0
        public static async Task ProcessTokensDeposited(MySqlConnection connection, string contractAddress, int blockchainID,
                                                        Web3 cl, IGrouping <string, EventLog <List <ParameterOutput> > > @group, EthApiService eth)
        {
            using (await LockManager.GetLock(LockType.TokensDeposited).Lock())
            {
                if (OTContract_Profile_TokensDeposited.TransactionExists(connection, @group.Key, blockchainID))
                {
                    return;
                }

                foreach (var eventLog in @group)
                {
                    var block = await BlockHelper.GetBlock(connection, eventLog.Log.BlockHash, eventLog.Log.BlockNumber,
                                                           cl,
                                                           blockchainID);

                    var profile = (string)eventLog.Event.FirstOrDefault(p => p.Parameter.Name == "profile")
                                  .Result;
                    var amountDeposited = Web3.Convert.FromWei((BigInteger)eventLog.Event
                                                               .FirstOrDefault(p => p.Parameter.Name == "amountDeposited").Result);
                    var newBalance = Web3.Convert.FromWei((BigInteger)eventLog.Event
                                                          .FirstOrDefault(p => p.Parameter.Name == "newBalance").Result);

                    var transaction =
                        eth.Transactions.GetTransactionByHash.SendRequestAsync(eventLog.Log.TransactionHash);

                    var receipt = eth.Transactions.GetTransactionReceipt.SendRequestAsync(eventLog.Log.TransactionHash);

                    await transaction;
                    await receipt;

                    OTContract_Profile_TokensDeposited.Insert(connection, new OTContract_Profile_TokensDeposited
                    {
                        BlockNumber     = block.BlockNumber,
                        TransactionHash = eventLog.Log.TransactionHash,
                        ContractAddress = contractAddress,
                        Profile         = profile,
                        AmountDeposited = amountDeposited,
                        NewBalance      = newBalance,
                        GasUsed         = (UInt64)receipt.Result.GasUsed.Value,
                        GasPrice        = (UInt64)transaction.Result.GasPrice.Value,
                        BlockchainID    = blockchainID
                    });
                }
            }
        }
示例#20
0
        private async Task Sync(MySqlConnection connection, Event profileCreatedEvent, Event identityCreatedEvent,
                                Event identityTransferredEvent, Event tokensDepositedEvent, Event tokensReleasedEvent,
                                Event tokensWithdrawnEvent, Event tokensTransferredEvent, Event tokensReservedEvent, OTContract contract,
                                Source source, Function createProfileFunction, Function transferProfileFunction, ulong start, ulong end,
                                int blockchainID, Web3 cl)
        {
            Logger.WriteLine(source, "Syncing profile " + start + " to " + end);

            var toBlock = new BlockParameter(end);

            var identityCreatedEvents = await identityCreatedEvent.GetAllChangesDefault(
                identityCreatedEvent.CreateFilterInput(new BlockParameter(start),
                                                       toBlock));

            var identityTransferredEvents = await identityTransferredEvent.GetAllChangesDefault(
                identityTransferredEvent.CreateFilterInput(new BlockParameter(start),
                                                           toBlock));

            var profileCreatedEvents = await profileCreatedEvent.GetAllChangesDefault(
                profileCreatedEvent.CreateFilterInput(new BlockParameter(start),
                                                      toBlock));

            var tokensDepositedEvents = await tokensDepositedEvent.GetAllChangesDefault(
                tokensDepositedEvent.CreateFilterInput(new BlockParameter(start),
                                                       toBlock));


            var tokensReleasedEvents = await tokensReleasedEvent.GetAllChangesDefault(
                tokensReleasedEvent.CreateFilterInput(new BlockParameter(start),
                                                      toBlock));


            var tokensWithdrawnEvents = await tokensWithdrawnEvent.GetAllChangesDefault(
                tokensWithdrawnEvent.CreateFilterInput(new BlockParameter(start),
                                                       toBlock));


            var tokensTransferredEvents = await tokensTransferredEvent.GetAllChangesDefault(
                tokensTransferredEvent.CreateFilterInput(new BlockParameter(start),
                                                         toBlock));


            var tokensReservedEvents = await tokensReservedEvent.GetAllChangesDefault(
                tokensReservedEvent.CreateFilterInput(new BlockParameter(start),
                                                      toBlock));


            if (identityCreatedEvents.Any())
            {
                Logger.WriteLine(source, "Found " + identityCreatedEvents.Count + " identity created events");
            }

            if (identityTransferredEvents.Any())
            {
                Logger.WriteLine(source, "Found " + identityTransferredEvents.Count + " identity transferred events");
            }

            if (profileCreatedEvents.Any())
            {
                Logger.WriteLine(source, "Found " + profileCreatedEvents.Count + " profile created events");
            }

            if (tokensDepositedEvents.Any())
            {
                Logger.WriteLine(source, "Found " + tokensDepositedEvents.Count + " tokens deposited events");
            }

            if (tokensReleasedEvents.Any())
            {
                Logger.WriteLine(source, "Found " + tokensReleasedEvents.Count + " tokens released events");
            }

            if (tokensWithdrawnEvents.Any())
            {
                Logger.WriteLine(source, "Found " + tokensWithdrawnEvents.Count + " tokens withdrawn events");
            }

            if (tokensTransferredEvents.Any())
            {
                Logger.WriteLine(source, "Found " + tokensTransferredEvents.Count + " tokens transferred events");
            }

            if (tokensReservedEvents.Any())
            {
                Logger.WriteLine(source, "Found " + tokensReservedEvents.Count + " tokens reserved events");
            }

            var eth = new EthApiService(cl.Client);

            foreach (EventLog <List <ParameterOutput> > eventLog in identityCreatedEvents)
            {
                await ProcessIdentityCreated(connection, contract.Address, blockchainID, cl, eventLog, eth);
            }

            foreach (EventLog <List <ParameterOutput> > eventLog in profileCreatedEvents)
            {
                await ProcessProfileCreated(connection, contract.Address, createProfileFunction, blockchainID, cl, eventLog, eth);
            }


            foreach (EventLog <List <ParameterOutput> > eventLog in identityTransferredEvents)
            {
                var block = await BlockHelper.GetBlock(connection, eventLog.Log.BlockHash, eventLog.Log.BlockNumber,
                                                       cl, blockchainID);

                var oldIdentity = (string)eventLog.Event
                                  .FirstOrDefault(p => p.Parameter.Name == "oldIdentity").Result;

                var newIdentity = (string)eventLog.Event
                                  .FirstOrDefault(p => p.Parameter.Name == "newIdentity").Result;

                var nodeId = HexHelper.ByteArrayToString((byte[])eventLog.Event
                                                         .FirstOrDefault(p => p.Parameter.Name == "nodeId").Result, false);


                var transaction = eth.Transactions.GetTransactionByHash.SendRequestAsync(eventLog.Log.TransactionHash);

                var receipt = eth.Transactions.GetTransactionReceipt.SendRequestAsync(eventLog.Log.TransactionHash);

                await transaction;
                await receipt;

                var row = new OTContract_Profile_IdentityTransferred
                {
                    TransactionHash = eventLog.Log.TransactionHash,
                    ContractAddress = contract.Address,
                    NewIdentity     = newIdentity,
                    BlockNumber     = (UInt64)eventLog.Log.BlockNumber.Value,
                    OldIdentity     = oldIdentity,
                    NodeId          = nodeId,
                    GasUsed         = (UInt64)receipt.Result.GasUsed.Value,
                    GasPrice        = (UInt64)transaction.Result.GasPrice.Value,
                    BlockchainID    = blockchainID
                };

                var transferProfileFunctionData = transferProfileFunction.DecodeInput(transaction.Result.Input);

                if (transferProfileFunctionData != null)
                {
                    row.ManagementWallet = (string)transferProfileFunctionData.FirstOrDefault(p => p.Parameter.Name == "managementWallet")?.Result;
                }


                OTContract_Profile_IdentityTransferred.InsertIfNotExist(connection, row);
            }


            foreach (var group in tokensDepositedEvents.GroupBy(t => t.Log.TransactionHash))
            {
                await ProcessTokensDeposited(connection, contract.Address, blockchainID, cl, @group, eth);
            }

            foreach (var group in tokensReleasedEvents.GroupBy(t => t.Log.TransactionHash))
            {
                await ProcessTokensReleased(connection, contract.Address, blockchainID, cl, @group, eth);
            }

            foreach (var group in tokensWithdrawnEvents.GroupBy(t => t.Log.TransactionHash))
            {
                await ProcessTokensWithdrawn(connection, contract.Address, blockchainID, cl, @group, eth);
            }

            foreach (var group in tokensTransferredEvents.GroupBy(t => t.Log.TransactionHash))
            {
                if (OTContract_Profile_TokensTransferred.TransactionExists(connection, group.Key, blockchainID))
                {
                    continue;
                }

                foreach (var eventLog in group)
                {
                    var sender = (string)eventLog.Event.FirstOrDefault(p => p.Parameter.Name == "sender")
                                 .Result;

                    var receiver = (string)eventLog.Event
                                   .FirstOrDefault(p => p.Parameter.Name == "receiver")
                                   .Result;
                    var amount = Web3.Convert.FromWei((BigInteger)eventLog.Event
                                                      .FirstOrDefault(p => p.Parameter.Name == "amount").Result);

                    var transaction = eth.Transactions.GetTransactionByHash.SendRequestAsync(eventLog.Log.TransactionHash);

                    var receipt = eth.Transactions.GetTransactionReceipt.SendRequestAsync(eventLog.Log.TransactionHash);

                    await transaction;
                    await receipt;

                    var block = await BlockHelper.GetBlock(connection, eventLog.Log.BlockHash,
                                                           eventLog.Log.BlockNumber,
                                                           cl, blockchainID);

                    OTContract_Profile_TokensTransferred.Insert(connection,
                                                                new OTContract_Profile_TokensTransferred
                    {
                        BlockNumber     = block.BlockNumber,
                        TransactionHash = eventLog.Log.TransactionHash,
                        ContractAddress = contract.Address,
                        Amount          = amount,
                        Receiver        = receiver,
                        Sender          = sender,
                        GasUsed         = (UInt64)receipt.Result.GasUsed.Value,
                        GasPrice        = (UInt64)transaction.Result.GasPrice.Value,
                        BlockchainID    = blockchainID
                    });
                }
            }

            foreach (var group in tokensReservedEvents.GroupBy(t => t.Log.TransactionHash))
            {
                if (OTContract_Profile_TokensReserved.TransactionExists(connection, group.Key, blockchainID))
                {
                    continue;
                }

                foreach (var eventLog in group)
                {
                    var block = await BlockHelper.GetBlock(connection, eventLog.Log.BlockHash,
                                                           eventLog.Log.BlockNumber,
                                                           cl, blockchainID);

                    var profile = (string)eventLog.Event.FirstOrDefault(p => p.Parameter.Name == "profile")
                                  .Result;
                    var amountReserved = Web3.Convert.FromWei((BigInteger)eventLog.Event
                                                              .FirstOrDefault(p => p.Parameter.Name == "amountReserved").Result);

                    var transaction = eth.Transactions.GetTransactionByHash.SendRequestAsync(eventLog.Log.TransactionHash);

                    var receipt = eth.Transactions.GetTransactionReceipt.SendRequestAsync(eventLog.Log.TransactionHash);

                    await transaction;
                    await receipt;

                    OTContract_Profile_TokensReserved.Insert(connection,
                                                             new OTContract_Profile_TokensReserved
                    {
                        TransactionHash = eventLog.Log.TransactionHash,
                        BlockNumber     = block.BlockNumber,
                        ContractAddress = contract.Address,
                        Profile         = profile,
                        AmountReserved  = amountReserved,
                        GasUsed         = (UInt64)receipt.Result.GasUsed.Value,
                        GasPrice        = (UInt64)transaction.Result.GasPrice.Value,
                        BlockchainID    = blockchainID
                    });
                }
            }

            contract.LastSyncedTimestamp = DateTime.Now;
            contract.SyncBlockNumber     = end;

            await OTContract.Update(connection, contract, false, false);
        }
        private async Task Sync(Source source, Event replacementCompletedEvent, OTContract contract,
                                MySqlConnection connection, Web3 cl, int blockchainID, EthApiService eth, ulong currentStart, ulong currentEnd)
        {
            var toBlock = new BlockParameter(currentEnd);

            var replacementCompletedEvents = await replacementCompletedEvent.GetAllChangesDefault(
                replacementCompletedEvent.CreateFilterInput(new BlockParameter(currentStart),
                                                            toBlock));


            if (replacementCompletedEvents.Any())
            {
                Logger.WriteLine(source, "Found " + replacementCompletedEvents.Count + " replacement completed events");
            }

            foreach (EventLog <List <ParameterOutput> > eventLog in replacementCompletedEvents)
            {
                var block = await BlockHelper.GetBlock(connection, eventLog.Log.BlockHash, eventLog.Log.BlockNumber,
                                                       cl, blockchainID);

                var offerId =
                    HexHelper.ByteArrayToString((byte[])eventLog.Event
                                                .First(e => e.Parameter.Name == "offerId").Result);

                var challengerIdentity = (string)eventLog.Event
                                         .First(e => e.Parameter.Name == "challengerIdentity").Result;

                var chosenHolder = (string)eventLog.Event
                                   .First(e => e.Parameter.Name == "chosenHolder").Result;

                var transaction = await eth.Transactions.GetTransactionByHash.SendRequestAsync(eventLog.Log.TransactionHash);

                var receipt = await eth.Transactions.GetTransactionReceipt.SendRequestAsync(eventLog.Log.TransactionHash);

                var row = new OTContract_Replacement_ReplacementCompleted
                {
                    TransactionHash    = eventLog.Log.TransactionHash,
                    BlockNumber        = (UInt64)eventLog.Log.BlockNumber.Value,
                    Timestamp          = block.Timestamp,
                    OfferId            = offerId,
                    ChosenHolder       = chosenHolder,
                    ChallengerIdentity = challengerIdentity,
                    GasPrice           = (UInt64)transaction.GasPrice.Value,
                    GasUsed            = (UInt64)receipt.GasUsed.Value,
                    BlockchainID       = blockchainID
                };

                await OTContract_Replacement_ReplacementCompleted.InsertIfNotExist(connection, row);

                await OTOfferHolder.Insert(connection, offerId, chosenHolder, false, blockchainID);

                await OTOfferHolder.UpdateLitigationStatusesForOffer(connection, offerId, blockchainID);
            }

            contract.LastSyncedTimestamp = DateTime.Now;
            contract.SyncBlockNumber     = (ulong)toBlock.BlockNumber.Value;

            await OTContract.Update(connection, contract, false, false);
        }
示例#22
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);
            }
        }
示例#23
0
        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
            });
        }
示例#24
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());
                }
            }
        }
        private async Task Sync(MySqlConnection connection, Event litigationInitiatedEvent,
                                Event litigationAnsweredEvent, Event litigationTimedOutEvent, Event litigationCompletedEvent,
                                Event replacementStartedEvent, OTContract contract, Source source, ulong start, ulong end, int blockchainID,
                                Web3 cl)
        {
            Logger.WriteLine(source, "Syncing litigation " + start + " to " + end);

            var toBlock = new BlockParameter(end);

            var litigationInitiatedEventsEventLogs = await litigationInitiatedEvent.GetAllChangesDefault(
                litigationInitiatedEvent.CreateFilterInput(new BlockParameter(start),
                                                           toBlock));


            var litigationAnsweredEvents = await litigationAnsweredEvent.GetAllChangesDefault(
                litigationAnsweredEvent.CreateFilterInput(new BlockParameter(start),
                                                          toBlock));

            var litigationTimedOutEvents = await litigationTimedOutEvent.GetAllChangesDefault(
                litigationTimedOutEvent.CreateFilterInput(new BlockParameter(start),
                                                          toBlock));


            var litigationCompletedEvents = await litigationCompletedEvent.GetAllChangesDefault(
                litigationCompletedEvent.CreateFilterInput(new BlockParameter(start),
                                                           toBlock));


            var replacementStartedEvents = await replacementStartedEvent.GetAllChangesDefault(
                replacementStartedEvent.CreateFilterInput(new BlockParameter(start),
                                                          toBlock));


            if (litigationInitiatedEventsEventLogs.Any())
            {
                Logger.WriteLine(source, "Found " + litigationInitiatedEventsEventLogs.Count + " litigation initiated events");
            }

            if (litigationAnsweredEvents.Any())
            {
                Logger.WriteLine(source, "Found " + litigationAnsweredEvents.Count + " litigation answered completed events");
            }

            if (litigationTimedOutEvents.Any())
            {
                Logger.WriteLine(source, "Found " + litigationTimedOutEvents.Count + " litigation timed out events");
            }

            if (litigationCompletedEvents.Any())
            {
                Logger.WriteLine(source, "Found " + litigationCompletedEvents.Count + " litigation completed events");
            }

            if (replacementStartedEvents.Any())
            {
                Logger.WriteLine(source, "Found " + replacementStartedEvents.Count + " replacement started events");
            }

            //var childTask = Task.Run(async () =>
            //{
            //    IEnumerable<IEventLog> items = litigationInitiatedEventsEventLogs
            //        .Union(litigationAnsweredEvents)
            //        .Union(litigationTimedOutEvents)
            //        .Union(litigationCompletedEvents)
            //        .Union(replacementStartedEvents);

            //    foreach (var eventLog in items)
            //    {
            //        await Program.GetEthBlock(connection, eventLog.Log.BlockHash, eventLog.Log.BlockNumber, cl);
            //    }
            //});

            var eth = new EthApiService(cl.Client);

            foreach (EventLog <List <ParameterOutput> > eventLog in litigationInitiatedEventsEventLogs)
            {
                await ProcessLitigationInitiated(connection, blockchainID, cl, eventLog, eth);
            }

            foreach (EventLog <List <ParameterOutput> > eventLog in litigationAnsweredEvents)
            {
                await ProcessLitigationAnswered(connection, blockchainID, cl, eventLog, eth);
            }

            foreach (EventLog <List <ParameterOutput> > eventLog in litigationTimedOutEvents)
            {
                await ProcessLitigationTimedOut(connection, blockchainID, cl, eventLog, eth);
            }

            foreach (EventLog <List <ParameterOutput> > eventLog in litigationCompletedEvents)
            {
                await ProcessLitigationCompleted(connection, blockchainID, cl, eventLog, eth);
            }

            foreach (EventLog <List <ParameterOutput> > eventLog in replacementStartedEvents)
            {
                await ProcessReplacementStarted(connection, blockchainID, cl, eventLog, eth);
            }

            contract.LastSyncedTimestamp = DateTime.Now;
            contract.SyncBlockNumber     = end;

            await OTContract.Update(connection, contract, false, false);

            //childTask.Wait();
        }
示例#26
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());
                }
            }
        }
示例#27
0
 public Contract(EthApiService eth, Type[] contractMessagesTypes, string contractAddress)
 {
     Eth             = eth;
     ContractBuilder = new ContractBuilder(contractMessagesTypes, contractAddress);
 }
示例#28
0
        public static async Task ProcessProfileCreated(MySqlConnection connection, string contractAddress,
                                                       Function createProfileFunction, int blockchainID, Web3 cl, EventLog <List <ParameterOutput> > eventLog, EthApiService eth)
        {
            using (await LockManager.GetLock(LockType.ProfileCreated).Lock())
            {
                var profile = (string)eventLog.Event.FirstOrDefault(p => p.Parameter.Name == "profile")
                              .Result;


                if (OTContract_Profile_ProfileCreated.Exists(connection, profile, blockchainID))
                {
                    return;
                }

                var block = await BlockHelper.GetBlock(connection, eventLog.Log.BlockHash, eventLog.Log.BlockNumber,
                                                       cl, blockchainID);

                var initialBalance = Web3.Convert.FromWei((BigInteger)eventLog.Event
                                                          .FirstOrDefault(p => p.Parameter.Name == "initialBalance").Result);


                var transaction = eth.Transactions.GetTransactionByHash.SendRequestAsync(eventLog.Log.TransactionHash);

                var receipt = eth.Transactions.GetTransactionReceipt.SendRequestAsync(eventLog.Log.TransactionHash);

                await transaction;
                await receipt;

                var row = new OTContract_Profile_ProfileCreated
                {
                    BlockNumber     = (UInt64)eventLog.Log.BlockNumber.Value,
                    TransactionHash = eventLog.Log.TransactionHash,
                    ContractAddress = contractAddress,
                    Profile         = profile,
                    InitialBalance  = initialBalance,
                    GasUsed         = (UInt64)receipt.Result.GasUsed.Value,
                    GasPrice        = (UInt64)transaction.Result.GasPrice.Value,
                    BlockchainID    = blockchainID
                };

                var createProfileInputData = createProfileFunction.DecodeInput(transaction.Result.Input);

                if (createProfileInputData != null)
                {
                    row.ManagementWallet =
                        (string)createProfileInputData.FirstOrDefault(p => p.Parameter.Name == "managementWallet")
                        ?.Result;

                    row.NodeId = HexHelper.ByteArrayToString((byte[])createProfileInputData
                                                             .FirstOrDefault(p => p.Parameter.Name == "profileNodeId").Result, false).Substring(0, 40);
                }

                OTContract_Profile_ProfileCreated.InsertIfNotExist(connection, row);
            }
        }