Exemple #1
0
        public async Task AddTransfer_Test()
        {
            var transfer = new TransferInfo()
            {
                BlockHeight = 0,
                From        = UInt160.Parse("0xf9df308b7bb380469354062f6b73f9cb0124317b"),
                FromBalance = 0,
                To          = UInt160.Parse("0x18c52425debcc3c76c06c3368044b8c60609a904"),

                ToBalance = 1,
                Asset     = NativeContract.NEO.Hash,
                Amount    = 1,
                TxId      = UInt256.Parse(""),
                TimeStamp = DateTime.Now.ToTimestamp(),
                AssetInfo = new AssetInfo()
                {
                    Asset    = NativeContract.NEO.Hash,
                    Name     = "NEO",
                    Symbol   = "neo",
                    Decimals = NativeContract.NEO.Decimals,
                },
            };

            _db.AddTransfer(transfer);
            //_db.Commit();
        }
        /// <summary>
        /// try to find "Transfer" event, then add record to db
        /// </summary>
        /// <param name="notification"></param>
        /// <param name="transaction"></param>
        /// <param name="block"></param>
        /// <param name="snapshot"></param>
        /// <returns></returns>
        private bool HasTransfer(NotificationInfo notification, Transaction transaction, Block block, SnapshotView snapshot)
        {
            var assetHash = UInt160.Parse(notification.Contract);
            var asset     = AssetCache.GetAssetInfo(assetHash, snapshot);

            if (asset == null)
            {
                //not nep5 asset
                return(false);
            }
            var notify = JStackItem.FromJson(notification.State);

            if (!(notify.Value is IList <JStackItem> notifyArray) || notifyArray.Count < 4)
            {
                return(false);
            }
            if (!"transfer".Equals(notifyArray[0].ValueString, StringComparison.OrdinalIgnoreCase))
            {
                return(false);
            }
            var from = notifyArray[1].Value as byte[];
            var to   = notifyArray[2].Value as byte[];

            if (from == null && to == null)
            {
                return(false);
            }
            if (!ConvertBigInteger(notifyArray[3], out var amount))
            {
                return(false);
            }

            var record = new TransferInfo
            {
                BlockHeight = block.Index,
                From        = from == null ? null : new UInt160(from),
                To          = to == null ? null : new UInt160(to),
                Asset       = asset.Asset,
                Amount      = amount,
                TxId        = transaction.Hash,
                TimeStamp   = block.Timestamp,
                AssetInfo   = asset,
            };

            _db.AddTransfer(record);

            if (record.From != null)
            {
                var fromBalance = record.From.GetBalanceOf(assetHash, snapshot);
                _db.UpdateBalance(record.From, asset, fromBalance.Value, snapshot.Height);
            }

            if (record.To != null && record.To != record.From)
            {
                var toBalance = record.To.GetBalanceOf(assetHash, snapshot);
                _db.UpdateBalance(record.To, asset, toBalance.Value, snapshot.Height);
            }
            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);
        }