From b74d1d49dccabf738820f5ffcee4a844c19514e7 Mon Sep 17 00:00:00 2001 From: Owen Zhang <38493437+superboyiii@users.noreply.github.com> Date: Thu, 2 Dec 2021 16:55:30 +0800 Subject: [PATCH] Remove Nep17Tracker (#677) --- src/RpcNep17Tracker/Helper.cs | 17 - src/RpcNep17Tracker/Nep17Balance.cs | 28 -- src/RpcNep17Tracker/Nep17BalanceKey.cs | 69 ---- src/RpcNep17Tracker/Nep17Transfer.cs | 36 -- src/RpcNep17Tracker/Nep17TransferKey.cs | 92 ----- src/RpcNep17Tracker/RpcNep17Tracker.cs | 321 ------------------ src/RpcNep17Tracker/RpcNep17Tracker.csproj | 16 - .../RpcNep17Tracker/config.json | 12 - 8 files changed, 591 deletions(-) delete mode 100644 src/RpcNep17Tracker/Helper.cs delete mode 100644 src/RpcNep17Tracker/Nep17Balance.cs delete mode 100644 src/RpcNep17Tracker/Nep17BalanceKey.cs delete mode 100644 src/RpcNep17Tracker/Nep17Transfer.cs delete mode 100644 src/RpcNep17Tracker/Nep17TransferKey.cs delete mode 100644 src/RpcNep17Tracker/RpcNep17Tracker.cs delete mode 100644 src/RpcNep17Tracker/RpcNep17Tracker.csproj delete mode 100644 src/RpcNep17Tracker/RpcNep17Tracker/config.json diff --git a/src/RpcNep17Tracker/Helper.cs b/src/RpcNep17Tracker/Helper.cs deleted file mode 100644 index 21966481e..000000000 --- a/src/RpcNep17Tracker/Helper.cs +++ /dev/null @@ -1,17 +0,0 @@ -using Neo.IO; -using Neo.IO.Data.LevelDB; -using System; -using System.Collections.Generic; - -namespace Neo.Plugins -{ - internal static class Helper - { - public static IEnumerable<(TKey, TValue)> FindRange(this DB db, byte[] startKeyBytes, byte[] endKeyBytes) - where TKey : IEquatable, ISerializable, new() - where TValue : class, ISerializable, new() - { - return db.FindRange(ReadOptions.Default, startKeyBytes, endKeyBytes, (k, v) => (k.AsSerializable(1), v.AsSerializable())); - } - } -} diff --git a/src/RpcNep17Tracker/Nep17Balance.cs b/src/RpcNep17Tracker/Nep17Balance.cs deleted file mode 100644 index 6b6aebe1a..000000000 --- a/src/RpcNep17Tracker/Nep17Balance.cs +++ /dev/null @@ -1,28 +0,0 @@ -using Neo.IO; -using System.IO; -using System.Numerics; - -namespace Neo.Plugins -{ - public class Nep17Balance : ISerializable - { - public BigInteger Balance; - public uint LastUpdatedBlock; - - int ISerializable.Size => - Balance.GetByteCount() + // Balance - sizeof(uint); // LastUpdatedBlock - - void ISerializable.Serialize(BinaryWriter writer) - { - writer.WriteVarBytes(Balance.ToByteArray()); - writer.Write(LastUpdatedBlock); - } - - void ISerializable.Deserialize(BinaryReader reader) - { - Balance = new BigInteger(reader.ReadVarBytes(512)); - LastUpdatedBlock = reader.ReadUInt32(); - } - } -} diff --git a/src/RpcNep17Tracker/Nep17BalanceKey.cs b/src/RpcNep17Tracker/Nep17BalanceKey.cs deleted file mode 100644 index 0d5e5267a..000000000 --- a/src/RpcNep17Tracker/Nep17BalanceKey.cs +++ /dev/null @@ -1,69 +0,0 @@ -using System; -using System.IO; -using Neo.IO; - -namespace Neo.Plugins -{ - public class Nep17BalanceKey : IComparable, IEquatable, ISerializable - { - public readonly UInt160 UserScriptHash; - public readonly UInt160 AssetScriptHash; - - public int Size => 20 + 20; - - public Nep17BalanceKey() : this(new UInt160(), new UInt160()) - { - } - - public Nep17BalanceKey(UInt160 userScriptHash, UInt160 assetScriptHash) - { - if (userScriptHash == null || assetScriptHash == null) - throw new ArgumentNullException(); - UserScriptHash = userScriptHash; - AssetScriptHash = assetScriptHash; - } - - public int CompareTo(Nep17BalanceKey other) - { - if (other is null) return 1; - if (ReferenceEquals(this, other)) return 0; - int result = UserScriptHash.CompareTo(other.UserScriptHash); - if (result != 0) return result; - return AssetScriptHash.CompareTo(other.AssetScriptHash); - } - - public bool Equals(Nep17BalanceKey other) - { - if (ReferenceEquals(null, other)) return false; - if (ReferenceEquals(this, other)) return true; - return UserScriptHash.Equals(other.UserScriptHash) && AssetScriptHash.Equals(AssetScriptHash); - } - - public override bool Equals(Object other) - { - return other is Nep17BalanceKey otherKey && Equals(otherKey); - } - - public override int GetHashCode() - { - unchecked - { - var hashCode = UserScriptHash.GetHashCode(); - hashCode = (hashCode * 397) ^ AssetScriptHash.GetHashCode(); - return hashCode; - } - } - - public void Serialize(BinaryWriter writer) - { - writer.Write(UserScriptHash); - writer.Write(AssetScriptHash); - } - - public void Deserialize(BinaryReader reader) - { - ((ISerializable)UserScriptHash).Deserialize(reader); - ((ISerializable)AssetScriptHash).Deserialize(reader); - } - } -} diff --git a/src/RpcNep17Tracker/Nep17Transfer.cs b/src/RpcNep17Tracker/Nep17Transfer.cs deleted file mode 100644 index 290e0d194..000000000 --- a/src/RpcNep17Tracker/Nep17Transfer.cs +++ /dev/null @@ -1,36 +0,0 @@ -using Neo.IO; -using System.IO; -using System.Numerics; - -namespace Neo.Plugins -{ - public class Nep17Transfer : ISerializable - { - public UInt160 UserScriptHash; - public uint BlockIndex; - public UInt256 TxHash; - public BigInteger Amount; - - int ISerializable.Size => - UInt160.Length + // UserScriptHash - sizeof(uint) + // BlockIndex - UInt256.Length + // TxHash - Amount.GetByteCount(); // Amount - - void ISerializable.Serialize(BinaryWriter writer) - { - writer.Write(UserScriptHash); - writer.Write(BlockIndex); - writer.Write(TxHash); - writer.WriteVarBytes(Amount.ToByteArray()); - } - - void ISerializable.Deserialize(BinaryReader reader) - { - UserScriptHash = reader.ReadSerializable(); - BlockIndex = reader.ReadUInt32(); - TxHash = reader.ReadSerializable(); - Amount = new BigInteger(reader.ReadVarBytes(512)); - } - } -} diff --git a/src/RpcNep17Tracker/Nep17TransferKey.cs b/src/RpcNep17Tracker/Nep17TransferKey.cs deleted file mode 100644 index 32a7fe847..000000000 --- a/src/RpcNep17Tracker/Nep17TransferKey.cs +++ /dev/null @@ -1,92 +0,0 @@ -using Neo.IO; -using System; -using System.Buffers.Binary; -using System.IO; - -namespace Neo.Plugins -{ - public class Nep17TransferKey : IComparable, IEquatable, ISerializable - { - public readonly UInt160 UserScriptHash; - public ulong TimestampMS { get; private set; } - public readonly UInt160 AssetScriptHash; - public ushort BlockXferNotificationIndex { get; private set; } - - public int Size => - UInt160.Length + //UserScriptHash - sizeof(ulong) + //TimestampMS - UInt160.Length + //AssetScriptHash - sizeof(ushort); //BlockXferNotificationIndex - - public Nep17TransferKey() : this(new UInt160(), 0, new UInt160(), 0) - { - } - - public Nep17TransferKey(UInt160 userScriptHash, ulong timestamp, UInt160 assetScriptHash, ushort xferIndex) - { - if (userScriptHash is null || assetScriptHash is null) - throw new ArgumentNullException(); - UserScriptHash = userScriptHash; - TimestampMS = timestamp; - AssetScriptHash = assetScriptHash; - BlockXferNotificationIndex = xferIndex; - } - - public int CompareTo(Nep17TransferKey other) - { - if (other is null) return 1; - if (ReferenceEquals(this, other)) return 0; - int result = UserScriptHash.CompareTo(other.UserScriptHash); - if (result != 0) return result; - int result2 = TimestampMS.CompareTo(other.TimestampMS); - if (result2 != 0) return result2; - int result3 = AssetScriptHash.CompareTo(other.AssetScriptHash); - if (result3 != 0) return result3; - return BlockXferNotificationIndex.CompareTo(other.BlockXferNotificationIndex); - } - - public bool Equals(Nep17TransferKey other) - { - if (ReferenceEquals(null, other)) return false; - if (ReferenceEquals(this, other)) return true; - return UserScriptHash.Equals(other.UserScriptHash) - && TimestampMS.Equals(other.TimestampMS) && AssetScriptHash.Equals(other.AssetScriptHash) - && BlockXferNotificationIndex.Equals(other.BlockXferNotificationIndex); - } - - public override bool Equals(Object other) - { - return other is Nep17TransferKey otherKey && Equals(otherKey); - } - - public override int GetHashCode() - { - unchecked - { - var hashCode = UserScriptHash.GetHashCode(); - hashCode = (hashCode * 397) ^ TimestampMS.GetHashCode(); - hashCode = (hashCode * 397) ^ AssetScriptHash.GetHashCode(); - hashCode = (hashCode * 397) ^ BlockXferNotificationIndex.GetHashCode(); - return hashCode; - } - } - - public void Serialize(BinaryWriter writer) - { - writer.Write(UserScriptHash); - if (BitConverter.IsLittleEndian) writer.Write(BinaryPrimitives.ReverseEndianness(TimestampMS)); - else writer.Write(TimestampMS); - writer.Write(AssetScriptHash); - writer.Write(BlockXferNotificationIndex); - } - - public void Deserialize(BinaryReader reader) - { - ((ISerializable)UserScriptHash).Deserialize(reader); - if (BitConverter.IsLittleEndian) TimestampMS = BinaryPrimitives.ReverseEndianness(reader.ReadUInt64()); - else TimestampMS = reader.ReadUInt64(); - ((ISerializable)AssetScriptHash).Deserialize(reader); - BlockXferNotificationIndex = reader.ReadUInt16(); - } - } -} diff --git a/src/RpcNep17Tracker/RpcNep17Tracker.cs b/src/RpcNep17Tracker/RpcNep17Tracker.cs deleted file mode 100644 index a760a5566..000000000 --- a/src/RpcNep17Tracker/RpcNep17Tracker.cs +++ /dev/null @@ -1,321 +0,0 @@ -using Neo.IO; -using Neo.IO.Data.LevelDB; -using Neo.IO.Json; -using Neo.Ledger; -using Neo.Network.P2P.Payloads; -using Neo.Persistence; -using Neo.SmartContract; -using Neo.SmartContract.Native; -using Neo.VM; -using Neo.Wallets; -using System; -using System.Buffers.Binary; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Numerics; -using static System.IO.Path; - -namespace Neo.Plugins -{ - public class RpcNep17Tracker : Plugin, IPersistencePlugin - { - private const byte Nep17BalancePrefix = 0xf8; - private const byte Nep17TransferSentPrefix = 0xf9; - private const byte Nep17TransferReceivedPrefix = 0xfa; - private DB _db; - private WriteBatch _writeBatch; - private string _dbPath; - private bool _shouldTrackHistory; - private bool _recordNullAddressHistory; - private uint _maxResults; - private uint _network; - private Snapshot _levelDbSnapshot; - private NeoSystem System; - - public override string Description => "Enquiries NEP-17 balances and transaction history of accounts through RPC"; - - protected override void OnSystemLoaded(NeoSystem system) - { - if (system.Settings.Network != _network) return; - System = system; - string path = string.Format(_dbPath, system.Settings.Network.ToString("X8")); - _db = DB.Open(GetFullPath(path), new Options { CreateIfMissing = true }); - RpcServerPlugin.RegisterMethods(this, _network); - } - - protected override void Configure() - { - _dbPath = GetConfiguration().GetSection("DBPath").Value ?? "Nep17BalanceData"; - _shouldTrackHistory = (GetConfiguration().GetSection("TrackHistory").Value ?? true.ToString()) != false.ToString(); - _recordNullAddressHistory = (GetConfiguration().GetSection("RecordNullAddressHistory").Value ?? false.ToString()) != false.ToString(); - _maxResults = uint.Parse(GetConfiguration().GetSection("MaxResults").Value ?? "1000"); - _network = uint.Parse(GetConfiguration().GetSection("Network").Value ?? "5195086"); - } - - private void ResetBatch() - { - _writeBatch = new WriteBatch(); - _levelDbSnapshot?.Dispose(); - _levelDbSnapshot = _db.GetSnapshot(); - } - - private static byte[] Key(byte prefix, ISerializable key) - { - byte[] buffer = new byte[key.Size + 1]; - using (MemoryStream ms = new MemoryStream(buffer, true)) - using (BinaryWriter writer = new BinaryWriter(ms)) - { - writer.Write(prefix); - key.Serialize(writer); - } - return buffer; - } - - private void Put(byte prefix, ISerializable key, ISerializable value) - { - _writeBatch.Put(Key(prefix, key), value.ToArray()); - } - - private void Delete(byte prefix, ISerializable key) - { - _writeBatch.Delete(Key(prefix, key)); - } - - private void RecordTransferHistory(DataCache snapshot, UInt160 scriptHash, UInt160 from, UInt160 to, BigInteger amount, UInt256 txHash, ref ushort transferIndex) - { - if (!_shouldTrackHistory) return; - - UInt256 hash = NativeContract.Ledger.CurrentHash(snapshot); - uint height = NativeContract.Ledger.CurrentIndex(snapshot); - TrimmedBlock block = NativeContract.Ledger.GetTrimmedBlock(snapshot, hash); - - if (_recordNullAddressHistory || from != UInt160.Zero) - { - Put(Nep17TransferSentPrefix, - new Nep17TransferKey(from, block.Header.Timestamp, scriptHash, transferIndex), - new Nep17Transfer - { - Amount = amount, - UserScriptHash = to, - BlockIndex = height, - TxHash = txHash - }); - } - - if (_recordNullAddressHistory || to != UInt160.Zero) - { - Put(Nep17TransferReceivedPrefix, - new Nep17TransferKey(to, block.Header.Timestamp, scriptHash, transferIndex), - new Nep17Transfer - { - Amount = amount, - UserScriptHash = from, - BlockIndex = height, - TxHash = txHash - }); - } - transferIndex++; - } - - private void HandleNotification(DataCache snapshot, IVerifiable scriptContainer, UInt160 scriptHash, string eventName, - VM.Types.Array stateItems, - Dictionary nep17BalancesChanged, ref ushort transferIndex) - { - if (eventName != "Transfer") return; - if (stateItems.Count != 3) return; - - if (!(stateItems[0].IsNull) && !(stateItems[0] is VM.Types.ByteString)) - return; - if (!(stateItems[1].IsNull) && !(stateItems[1] is VM.Types.ByteString)) - return; - var amountItem = stateItems[2]; - if (!(amountItem is VM.Types.ByteString || amountItem is VM.Types.Integer)) - return; - byte[] fromBytes = stateItems[0].IsNull ? null : stateItems[0].GetSpan().ToArray(); - if (fromBytes != null && fromBytes.Length != UInt160.Length) - return; - byte[] toBytes = stateItems[1].IsNull ? null : stateItems[1].GetSpan().ToArray(); - if (toBytes != null && toBytes.Length != UInt160.Length) - return; - if (fromBytes == null && toBytes == null) return; - - var from = UInt160.Zero; - var to = UInt160.Zero; - - if (fromBytes != null) - { - from = new UInt160(fromBytes); - var fromKey = new Nep17BalanceKey(from, scriptHash); - if (!nep17BalancesChanged.ContainsKey(fromKey)) nep17BalancesChanged.Add(fromKey, new Nep17Balance()); - } - - if (toBytes != null) - { - to = new UInt160(toBytes); - var toKey = new Nep17BalanceKey(to, scriptHash); - if (!nep17BalancesChanged.ContainsKey(toKey)) nep17BalancesChanged.Add(toKey, new Nep17Balance()); - } - if (scriptContainer is Transaction transaction) - { - RecordTransferHistory(snapshot, scriptHash, from, to, amountItem.GetInteger(), transaction.Hash, ref transferIndex); - } - } - - void IPersistencePlugin.OnPersist(NeoSystem system, Block block, DataCache snapshot, IReadOnlyList applicationExecutedList) - { - if (system.Settings.Network != _network) return; - // Start freshly with a new DBCache for each block. - ResetBatch(); - Dictionary nep17BalancesChanged = new Dictionary(); - - ushort transferIndex = 0; - foreach (Blockchain.ApplicationExecuted appExecuted in applicationExecutedList) - { - // Executions that fault won't modify storage, so we can skip them. - if (appExecuted.VMState.HasFlag(VMState.FAULT)) continue; - foreach (var notifyEventArgs in appExecuted.Notifications) - { - if (!(notifyEventArgs?.State is VM.Types.Array stateItems) || stateItems.Count == 0) - continue; - HandleNotification(snapshot, notifyEventArgs.ScriptContainer, notifyEventArgs.ScriptHash, notifyEventArgs.EventName, - stateItems, nep17BalancesChanged, ref transferIndex); - } - } - - foreach (var nep17BalancePair in nep17BalancesChanged) - { - // get guarantee accurate balances by calling balanceOf for keys that changed. - byte[] script; - using (ScriptBuilder sb = new ScriptBuilder()) - { - sb.EmitDynamicCall(nep17BalancePair.Key.AssetScriptHash, "balanceOf", nep17BalancePair.Key.UserScriptHash.ToArray()); - script = sb.ToArray(); - } - - using (ApplicationEngine engine = ApplicationEngine.Run(script, snapshot, settings: system.Settings)) - { - if (engine.State.HasFlag(VMState.FAULT)) continue; - if (engine.ResultStack.Count <= 0) continue; - nep17BalancePair.Value.Balance = engine.ResultStack.Pop().GetInteger(); - } - nep17BalancePair.Value.LastUpdatedBlock = block.Index; - if (nep17BalancePair.Value.Balance.IsZero) - { - Delete(Nep17BalancePrefix, nep17BalancePair.Key); - continue; - } - Put(Nep17BalancePrefix, nep17BalancePair.Key, nep17BalancePair.Value); - } - } - - void IPersistencePlugin.OnCommit(NeoSystem system, Block block, DataCache snapshot) - { - if (system.Settings.Network != _network) return; - _db.Write(WriteOptions.Default, _writeBatch); - } - - bool IPersistencePlugin.ShouldThrowExceptionFromCommit(Exception ex) - { - return true; - } - - private void AddTransfers(byte dbPrefix, UInt160 userScriptHash, ulong startTime, ulong endTime, - JArray parentJArray) - { - var prefix = new[] { dbPrefix }.Concat(userScriptHash.ToArray()).ToArray(); - byte[] startTimeBytes, endTimeBytes; - if (BitConverter.IsLittleEndian) - { - startTimeBytes = BitConverter.GetBytes(BinaryPrimitives.ReverseEndianness(startTime)); - endTimeBytes = BitConverter.GetBytes(BinaryPrimitives.ReverseEndianness(endTime)); - } - else - { - startTimeBytes = BitConverter.GetBytes(startTime); - endTimeBytes = BitConverter.GetBytes(endTime); - } - - var transferPairs = _db.FindRange( - prefix.Concat(startTimeBytes).ToArray(), - prefix.Concat(endTimeBytes).ToArray()); - - int resultCount = 0; - foreach (var (key, value) in transferPairs) - { - if (++resultCount > _maxResults) break; - JObject transfer = new JObject(); - transfer["timestamp"] = key.TimestampMS; - transfer["assethash"] = key.AssetScriptHash.ToString(); - transfer["transferaddress"] = value.UserScriptHash == UInt160.Zero ? null : value.UserScriptHash.ToAddress(System.Settings.AddressVersion); - transfer["amount"] = value.Amount.ToString(); - transfer["blockindex"] = value.BlockIndex; - transfer["transfernotifyindex"] = key.BlockXferNotificationIndex; - transfer["txhash"] = value.TxHash.ToString(); - parentJArray.Add(transfer); - } - } - - private UInt160 GetScriptHashFromParam(string addressOrScriptHash) - { - return addressOrScriptHash.Length < 40 ? - addressOrScriptHash.ToScriptHash(System.Settings.AddressVersion) : UInt160.Parse(addressOrScriptHash); - } - - [RpcMethod] - public JObject GetNep17Transfers(JArray _params) - { - if (!_shouldTrackHistory) throw new RpcException(-32601, "Method not found"); - UInt160 userScriptHash = GetScriptHashFromParam(_params[0].AsString()); - // If start time not present, default to 1 week of history. - ulong startTime = _params.Count > 1 ? (ulong)_params[1].AsNumber() : - (DateTime.UtcNow - TimeSpan.FromDays(7)).ToTimestampMS(); - ulong endTime = _params.Count > 2 ? (ulong)_params[2].AsNumber() : DateTime.UtcNow.ToTimestampMS(); - - if (endTime < startTime) throw new RpcException(-32602, "Invalid params"); - - JObject json = new JObject(); - JArray transfersSent = new JArray(); - json["sent"] = transfersSent; - JArray transfersReceived = new JArray(); - json["received"] = transfersReceived; - json["address"] = userScriptHash.ToAddress(System.Settings.AddressVersion); - AddTransfers(Nep17TransferSentPrefix, userScriptHash, startTime, endTime, transfersSent); - AddTransfers(Nep17TransferReceivedPrefix, userScriptHash, startTime, endTime, transfersReceived); - return json; - } - - [RpcMethod] - public JObject GetNep17Balances(JArray _params) - { - UInt160 userScriptHash = GetScriptHashFromParam(_params[0].AsString()); - - JObject json = new JObject(); - JArray balances = new JArray(); - json["balance"] = balances; - json["address"] = userScriptHash.ToAddress(System.Settings.AddressVersion); - - using (Iterator it = _db.NewIterator(ReadOptions.Default)) - { - byte[] prefix = Key(Nep17BalancePrefix, userScriptHash); - for (it.Seek(prefix); it.Valid(); it.Next()) - { - ReadOnlySpan key_bytes = it.Key(); - if (!key_bytes.StartsWith(prefix)) break; - Nep17BalanceKey key = key_bytes[1..].AsSerializable(); - if (NativeContract.ContractManagement.GetContract(System.StoreView, key.AssetScriptHash) is null) - continue; - Nep17Balance value = it.Value().AsSerializable(); - balances.Add(new JObject - { - ["assethash"] = key.AssetScriptHash.ToString(), - ["amount"] = value.Balance.ToString(), - ["lastupdatedblock"] = value.LastUpdatedBlock - }); - } - } - - return json; - } - } -} diff --git a/src/RpcNep17Tracker/RpcNep17Tracker.csproj b/src/RpcNep17Tracker/RpcNep17Tracker.csproj deleted file mode 100644 index bb3b93e44..000000000 --- a/src/RpcNep17Tracker/RpcNep17Tracker.csproj +++ /dev/null @@ -1,16 +0,0 @@ - - - Neo.Plugins.RpcNep17Tracker - Neo.Plugins - - - - PreserveNewest - PreserveNewest - - - - - - - diff --git a/src/RpcNep17Tracker/RpcNep17Tracker/config.json b/src/RpcNep17Tracker/RpcNep17Tracker/config.json deleted file mode 100644 index 2f9238e47..000000000 --- a/src/RpcNep17Tracker/RpcNep17Tracker/config.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "PluginConfiguration": { - "DBPath": "Nep17BalanceData", - "TrackHistory": true, - "RecordNullAddressHistory": false, - "MaxResults": 1000, - "Network": 860833102 - }, - "Dependency": [ - "RpcServer" - ] -}