/// <summary> /// analysis block transaction execute result logs /// </summary> /// <param name="blockHeight"></param> /// <returns></returns> public async Task <bool> Sync(uint blockHeight) { if (blockHeight > Blockchain.Singleton.Height) { return(false); } if (_db.HasSyncIndex(blockHeight)) { return(true); } var block = Blockchain.Singleton.GetBlock(blockHeight); if (block.Transactions.IsEmpty()) { return(true); } using var snapshot = Blockchain.Singleton.GetSnapshot(); foreach (var transaction in block.Transactions) { _db.AddTransaction(new TransactionInfo() { TxId = transaction.Hash, BlockHeight = blockHeight, Sender = transaction.Sender, Time = block.Timestamp.FromTimestampMS(), }); var executeResult = _db.GetExecuteLog(transaction.Hash); if (executeResult == null || executeResult.VMState.HasFlag(VMState.FAULT) || executeResult.Notifications.IsEmpty()) { continue; } foreach (var notification in executeResult.Notifications) { HasTransfer(notification, transaction, block, snapshot); } //shouldCommit = executeResult.Notifications.Aggregate(shouldCommit, (current, notification) => current | HasTransfer(notification, transaction, block, snapshot)); } _db.AddSyncIndex(blockHeight); _db.Commit(); Console.WriteLine($"Syncing:{_scanHeight}"); if (_db.LiveTime.TotalSeconds > 15) { //release memory _db.Dispose(); _db = new TrackDB(); } return(true); }
/// <summary> /// analysis block transaction execute result logs /// </summary> /// <param name="blockHeight"></param> /// <returns></returns> public async Task <bool> Sync(uint blockHeight) { if (blockHeight > this.GetCurrentHeight()) { return(false); } if (_db.HasSyncIndex(blockHeight)) { return(true); } var block = blockHeight.GetBlock(); var blockTime = block.Timestamp.FromTimestampMS(); //var balanceChanges = new HashSet<(UInt160 account, UInt160 asset)>(); foreach (var transaction in block.Transactions) { _db.AddTransaction(new TransactionInfo() { TxId = transaction.Hash, BlockHeight = blockHeight, Sender = transaction.Sender, Time = blockTime, }); //balanceChanges.Add((transaction.Sender, NativeContract.GAS.Hash)); var invokeMethods = GetInvokeMethods(transaction); if (invokeMethods.NotEmpty()) { foreach (var invokeMethod in invokeMethods) { _db.AddInvokeTransaction(transaction.Hash, invokeMethod.contract, string.Join(',', invokeMethod.methods)); } } } SyncContracts(blockHeight, blockTime); var transfers = new List <TransferInfo>(); var transferItems = _levelDb.GetTransfers(blockHeight); if (transferItems.NotEmpty()) { foreach (var item in transferItems) { transfers.Add(new TransferInfo() { BlockHeight = blockHeight, TimeStamp = block.Timestamp, TxId = item.TxId, From = item.From, To = item.To, Amount = item.Amount, Asset = item.Asset, Trigger = item.Trigger, }); } } foreach (var transferInfo in transfers) { _db.AddTransfer(transferInfo); } var balanceChanges = _levelDb.GetBalancingAccounts(blockHeight); if (balanceChanges.NotEmpty()) { var snapshot = this.GetDefaultSnapshot(); foreach (var balanceChange in balanceChanges) { UpdateBalance(balanceChange.Account, balanceChange.Asset, snapshot); } } _db.AddSyncIndex(blockHeight); _db.Commit(); Console.WriteLine($"Synced:{_scanHeight}"); if (_db.LiveTime.TotalSeconds > 15) { //release memory _db.Dispose(); _db = new TrackDB(); } return(true); }