private async Task SyncContractsChanged(Event contractsChangedEvent, ulong fromBlockNumber, ulong toBlockNumber, Contract hubContract, Web3 web3, MySqlConnection connection, int blockchainID) { var eventsOfChange = await contractsChangedEvent.GetAllChangesDefault( contractsChangedEvent.CreateFilterInput(new BlockParameter(fromBlockNumber), new BlockParameter(toBlockNumber))); foreach (var eventLog in eventsOfChange) { Function setContractAddressFunction = hubContract.GetFunction("setContractAddress"); var transaction = await web3.Eth.Transactions.GetTransactionByHash.SendRequestAsync(eventLog.Log.TransactionHash); var data = setContractAddressFunction.DecodeInput(transaction.Input); if (data == null) { continue; } var contractName = (string)data.First(d => d.Parameter.Name == "contractName").Result; var newContractAddress = (string)data.First(d => d.Parameter.Name == "newContractAddress").Result; if (Enum.TryParse(typeof(ContractTypeEnum), contractName, true, out var result)) { await OTContract.InsertOrUpdate(connection, new OTContract(fromBlockNumber, fromBlockNumber) { Address = newContractAddress, IsLatest = false, Type = (int)result, BlockchainID = blockchainID }, true); } } await HubAddress.UpdateSyncBlockNumber(connection, blockchainID, hubContract.Address, toBlockNumber); }
private async Task <HubAddress> GetHubAddressModel(MySqlConnection connection, string hubAddress, int blockchainID, bool isLatest) { ulong fromBlockNumber = await connection.ExecuteScalarAsync <UInt64>( "SELECT FromBlockNumber FROM blockchains where id = @id", new { id = blockchainID }); if (!await HubAddress.Exists(connection, blockchainID, hubAddress)) { await HubAddress.Insert(connection, blockchainID, hubAddress, fromBlockNumber); } HubAddress hubAddressModel = await HubAddress.GetByID(connection, blockchainID, hubAddress); if (!isLatest && !hubAddressModel.DateReplaced.HasValue) { await HubAddress.MarkAsReplaced(connection, blockchainID, hubAddress); } return(hubAddressModel); }
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); }