private List <Task <InteropBlock> > CreateTaskList(BigInteger batchCount, BigInteger[] blockIds = null) { List <Task <InteropBlock> > taskList = new List <Task <InteropBlock> >(); if (blockIds == null) { var _interopBlockHeight = BigInteger.Parse(OracleReader.GetCurrentHeight("neo", "neo")); var nextCurrentBlockHeight = _interopBlockHeight + batchCount; for (var i = _interopBlockHeight; i < nextCurrentBlockHeight; i++) { var url = DomainExtensions.GetOracleBlockURL( "neo", "neo", PBigInteger.FromUnsignedArray(i.ToByteArray(), true)); taskList.Add(CreateTask(url)); } } else { foreach (var blockId in blockIds) { var url = DomainExtensions.GetOracleBlockURL( "neo", "neo", PBigInteger.FromUnsignedArray(blockId.ToByteArray(), true)); taskList.Add(CreateTask(url)); } } return(taskList); }
private InteropBlock GetInteropBlock(BigInteger blockId) { var url = DomainExtensions.GetOracleBlockURL( "neo", "neo", PBigInteger.FromUnsignedArray(blockId.ToByteArray(), true)); return(OracleReader.Read <InteropBlock>(DateTime.Now, url)); }
public void OracleTestWithTooMuchData() { var owner = PhantasmaKeys.Generate(); var wallet = PhantasmaKeys.Generate(); var nexus = new Nexus("simnet", null, null); nexus.SetOracleReader(new OracleSimulator(nexus)); var simulator = new NexusSimulator(nexus, owner, 1234); for (int i = 0; i < DomainSettings.MaxOracleEntriesPerBlock + 1; i++) { var url = DomainExtensions.GetOracleBlockURL("neo", "neo", new BigInteger(i)); var iBlock = nexus.GetOracleReader().Read <InteropBlock>(DateTime.Now, url); } Assert.ThrowsException <ChainException>(() => { simulator.BeginBlock(); simulator.GenerateTransfer(owner, wallet.Address, nexus.RootChain, "SOUL", 100); simulator.EndBlock().First(); }); }
public void OracleTestWithData() { var owner = PhantasmaKeys.Generate(); var wallet = PhantasmaKeys.Generate(); var nexus = new Nexus("simnet", null, null); nexus.SetOracleReader(new OracleSimulator(nexus)); var simulator = new NexusSimulator(nexus, owner, 1234); //for (var i = 0; i < 65536; i++) for (var i = 0; i < 100; i++) { var url = DomainExtensions.GetOracleBlockURL("neo", "neo", new BigInteger(i)); var iBlock = nexus.GetOracleReader().Read <InteropBlock>(DateTime.Now, url); } simulator.BeginBlock(); simulator.GenerateTransfer(owner, wallet.Address, nexus.RootChain, "SOUL", 100); var block = simulator.EndBlock().First(); Console.WriteLine("block oracle data: " + block.OracleData.Count()); Assert.IsTrue(block.OracleData.Count() == 100); }
public override IEnumerable <PendingSwap> Update() { lock (String.Intern("PendingSetCurrentHeight_" + "neo")) { var result = new List <PendingSwap>(); try { var _interopBlockHeight = BigInteger.Parse(OracleReader.GetCurrentHeight("neo", "neo")); // initial start, we have to verify all processed swaps if (initialStart) { Logger.Debug($"Read all neo blocks now."); // TODO check if quick sync nodes are configured, if so use quick sync // we need to find a better solution for that though var allInteropBlocks = OracleReader.ReadAllBlocks("neo", "neo"); Logger.Debug($"Found {allInteropBlocks.Count} blocks"); foreach (var block in allInteropBlocks) { try { ProcessBlock(block, result); } catch (Exception e) { Logger.Debug($"Block {block.Hash} was not processed correctly: " + e); } } initialStart = false; Logger.Debug($"QuickSync: " + quickSync); // quick sync is only done once after startup if (quickSync) { // if quick sync is active, we can use a specific plugin installed on the nodes (EventTracker) try { var blockIds = neoAPI.GetSwapBlocks("ed07cffad18f1308db51920d99a2af60ac66a7b3", LocalAddress, _interopBlockHeight.ToString()); Logger.Debug($"Found {blockIds.Count} blocks to process "); List <InteropBlock> blockList = new List <InteropBlock>(); foreach (var entry in blockIds) { //logger.Debug($"read block {entry.Value}"); var url = DomainExtensions.GetOracleBlockURL("neo", "neo", PBigInteger.Parse(entry.Value.ToString())); blockList.Add(OracleReader.Read <InteropBlock>(DateTime.Now, url)); } // get blocks and order them for processing var blocksToProcess = blockList.Where(x => blockIds.ContainsKey(x.Hash.ToString())) .Select(x => new { block = x, id = blockIds[x.Hash.ToString()] }) .OrderBy(x => x.id); Logger.Debug($"blocks to process: {blocksToProcess.Count()}"); foreach (var entry in blocksToProcess.OrderBy(x => x.id)) { Logger.Debug($"process block {entry.id}"); ProcessBlock(entry.block, result); OracleReader.SetCurrentHeight("neo", "neo", _interopBlockHeight.ToString()); _interopBlockHeight = BigInteger.Parse(entry.id.ToString()); } } catch (Exception e) { Logger.Error("Inital start failed: " + e.ToString()); } } // return after the initial start to be able to process all swaps that happend in the mean time. return(result); } var blockIterator = new BlockIterator(neoAPI); var blockDifference = blockIterator.currentBlock - _interopBlockHeight; var batchCount = (blockDifference > 8) ? 8 : blockDifference; //TODO make it a constant, should be no more than 8 while (blockIterator.currentBlock > _interopBlockHeight) { if (_resyncBlockIds.Any()) { for (var i = 0; i < _resyncBlockIds.Count; i++) { var blockId = _resyncBlockIds.ElementAt(i); if (blockId > _interopBlockHeight) { Logger.Debug($"NeoInterop: Update() resync block {blockId} higher than current interop height, can't resync."); _resyncBlockIds.RemoveAt(i); continue; } try { Logger.Debug($"NeoInterop: Update() resync block {blockId} now."); var interopBlock = GetInteropBlock(blockId); ProcessBlock(interopBlock, result); } catch (Exception e) { Logger.Error($"NeoInterop: Update() resync block {blockId} failed: " + e); } _resyncBlockIds.RemoveAt(i); } } Logger.Debug($"Swaps: Current Neo chain height: {blockIterator.currentBlock}, interop: {_interopBlockHeight}, delta: {blockIterator.currentBlock - _interopBlockHeight}"); blockDifference = blockIterator.currentBlock - _interopBlockHeight; batchCount = (blockDifference > 8) ? 8 : blockDifference; if (batchCount > 1) { List <Task <InteropBlock> > taskList = CreateTaskList(batchCount); foreach (var task in taskList) { task.Start(); } Task.WaitAll(taskList.ToArray()); foreach (var task in taskList) { var block = task.Result; ProcessBlock(block, result); } OracleReader.SetCurrentHeight("neo", "neo", _interopBlockHeight.ToString()); _interopBlockHeight += batchCount; } else { var interopBlock = GetInteropBlock(_interopBlockHeight); ProcessBlock(interopBlock, result); OracleReader.SetCurrentHeight("neo", "neo", _interopBlockHeight.ToString()); _interopBlockHeight++; } } } catch (Exception e) { Logger.Error("Neo block sync failed: " + e); } return(result); } }
public override IEnumerable <PendingSwap> Update() { // wait another 10s to execute eth interop //Task.Delay(10000).Wait(); try { lock (String.Intern("PendingSetCurrentHeight_" + BSCWallet.BSCPlatform)) { var result = new List <PendingSwap>(); // initial start, we have to verify all processed swaps if (initialStart) { Logger.Debug($"Read all bsc blocks now."); var allInteropBlocks = OracleReader.ReadAllBlocks(BSCWallet.BSCPlatform, BSCWallet.BSCPlatform); Logger.Debug($"Found {allInteropBlocks.Count} blocks"); foreach (var block in allInteropBlocks) { ProcessBlock(block, ref result); } initialStart = false; // return after the initial start to be able to process all swaps that happend in the mean time. return(result); } var currentHeight = ethAPI.GetBlockHeight(); var _interopBlockHeight = BigInteger.Parse(OracleReader.GetCurrentHeight(BSCWallet.BSCPlatform, BSCWallet.BSCPlatform)); Logger.Debug($"Swaps: Current Eth chain height: {currentHeight}, interop: {_interopBlockHeight}, delta: {currentHeight - _interopBlockHeight}"); var blocksProcessedInOneBatch = 0; while (blocksProcessedInOneBatch < 50) { if (_resyncBlockIds.Any()) { for (var i = 0; i < _resyncBlockIds.Count; i++) { var blockId = _resyncBlockIds.ElementAt(i); if (blockId > _interopBlockHeight) { this.Logger.Warning($"EthInterop:Update() resync block {blockId} higher than current interop height, can't resync."); _resyncBlockIds.RemoveAt(i); continue; } try { this.Logger.Debug($"EthInterop:Update() resync block {blockId} now."); var block = GetInteropBlock(blockId); ProcessBlock(block, ref result); } catch (Exception e) { this.Logger.Error($"EthInterop:Update() resync block {blockId} failed: " + e); } _resyncBlockIds.RemoveAt(i); } } blocksProcessedInOneBatch++; var blockDifference = currentHeight - _interopBlockHeight; if (blockDifference < confirmations) { // no need to query the node yet break; } //TODO quick sync not done yet, requieres a change to the oracle impl to fetch multiple blocks //var nextHeight = (blockDifference > 50) ? 50 : blockDifference; //TODO //var transfers = new Dictionary<string, Dictionary<string, List<InteropTransfer>>>(); //if (nextHeight > 1) //{ // var blockCrawler = new EthBlockCrawler(logger, contracts.ToArray(), 0/*confirmations*/, ethAPI); //TODO settings confirmations // blockCrawler.Fetch(currentHeight, nextHeight); // transfers = blockCrawler.ExtractInteropTransfers(logger, LocalAddress); // foreach (var entry in transfers) // { // foreach (var txInteropTransfer in entry.Value) // { // foreach (var interopTransfer in txInteropTransfer.Value) // { // result.Add(new PendingSwap( // this.PlatformName // ,Hash.Parse(entry.Key) // ,interopTransfer.sourceAddress // ,interopTransfer.interopAddress) // ); // } // } // } // _interopBlockHeight = nextHeight; // oracleReader.SetCurrentHeight(BSCWallet.BSCPlatform, BSCWallet.BSCPlatform, _interopBlockHeight.ToString()); //} //else //{ /* Future improvement, implement oracle call to fetch multiple blocks */ var url = DomainExtensions.GetOracleBlockURL( BSCWallet.BSCPlatform, BSCWallet.BSCPlatform, PBigInteger.FromUnsignedArray(_interopBlockHeight.ToByteArray(), true)); var interopBlock = OracleReader.Read <InteropBlock>(DateTime.Now, url); ProcessBlock(interopBlock, ref result); _interopBlockHeight++; //} } OracleReader.SetCurrentHeight(BSCWallet.BSCPlatform, BSCWallet.BSCPlatform, _interopBlockHeight.ToString()); var total = result.Count(); if (total > 0) { Logger.Message($"startup: found {total} bsc swaps"); } else { Logger.Debug($"did not find any bsc swaps"); } return(result); } } catch (Exception e) { var logMessage = "BSCInterop.Update() exception caught:\n" + e.Message; var inner = e.InnerException; while (inner != null) { logMessage += "\n---> " + inner.Message + "\n\n" + inner.StackTrace; inner = inner.InnerException; } logMessage += "\n\n" + e.StackTrace; Logger.Error(logMessage); return(new List <PendingSwap>()); } }