Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add plugin for NEP5 balances and transfer history (Persistence + RPC) #43

Merged
merged 14 commits into from
Mar 9, 2019
33 changes: 33 additions & 0 deletions RpcNep5Balances/Helper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using Neo.IO;
using Neo.IO.Data.LevelDB;

namespace Neo.Plugins
{
internal static class Helper
{
public static IEnumerable<T> FindRange<T>(this DB db, ReadOptions options, Slice startKey, Slice endKey, Func<Slice, Slice, T> resultSelector)
{
using (Iterator it = db.NewIterator(options))
{
for (it.Seek(startKey); it.Valid(); it.Next())
{
Slice key = it.Key();
if (key > endKey) break;
yield return resultSelector(key, it.Value());
}
}
}

public static IEnumerable<KeyValuePair<TKey, TValue>> FindRange<TKey, TValue>(this DB db, byte[] startKeyBytes, byte[] endKeyBytes)
where TKey : IEquatable<TKey>, ISerializable, new()
where TValue : class, ICloneable<TValue>, ISerializable, new()
{
return db.FindRange(null, SliceBuilder.Begin().Add(startKeyBytes),
SliceBuilder.Begin().Add(endKeyBytes),
(k, v) => new KeyValuePair<TKey, TValue>(k.ToArray().AsSerializable<TKey>(1),
v.ToArray().AsSerializable<TValue>()));
}
}
}
42 changes: 42 additions & 0 deletions RpcNep5Balances/Nep5Balance.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using System.IO;
using System.Numerics;
using Neo.IO;
using Neo.Ledger;

namespace Neo.Plugins
{
public class Nep5Balance : StateBase, ICloneable<Nep5Balance>
{
public BigInteger Balance;
public uint LastUpdatedBlock;

public override int Size => base.Size + Balance.ToByteArray().GetVarSize();

public override void Serialize(BinaryWriter writer)
{
base.Serialize(writer);
writer.WriteVarBytes(Balance.ToByteArray());
}

public override void Deserialize(BinaryReader reader)
{
base.Deserialize(reader);
Balance = new BigInteger(reader.ReadVarBytes(512));
}

public Nep5Balance Clone()
{
return new Nep5Balance
{
Balance = Balance,
LastUpdatedBlock = LastUpdatedBlock
};
}

public void FromReplica(Nep5Balance replica)
{
Balance = replica.Balance;
LastUpdatedBlock = replica.LastUpdatedBlock;
}
}
}
69 changes: 69 additions & 0 deletions RpcNep5Balances/Nep5BalanceKey.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
using System;
using System.IO;
using Neo.IO;

namespace Neo.Plugins
{
public class Nep5BalanceKey : IComparable<Nep5BalanceKey>, IEquatable<Nep5BalanceKey>, ISerializable
{
public readonly UInt160 UserScriptHash;
public readonly UInt160 AssetScriptHash;

public Nep5BalanceKey() : this(new UInt160(), new UInt160())
{
}

public Nep5BalanceKey(UInt160 userScriptHash, UInt160 assetScriptHash)
{
if (userScriptHash == null || assetScriptHash == null)
throw new ArgumentNullException();
UserScriptHash = userScriptHash;
AssetScriptHash = assetScriptHash;
}

public int CompareTo(Nep5BalanceKey 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(Nep5BalanceKey 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 Nep5BalanceKey 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);
}

public int Size { get; } = 20 + 20;
}
}
55 changes: 55 additions & 0 deletions RpcNep5Balances/Nep5Transfer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using System.IO;
using System.Numerics;
using Neo.IO;
using Neo.Ledger;
using Neo.Network.P2P.Payloads;

namespace Neo.Plugins
{
public class Nep5Transfer : StateBase, ICloneable<Nep5Transfer>
{
public UInt160 UserScriptHash;
public uint BlockIndex;
public UInt256 TxHash;
public BigInteger Amount;

public override int Size => base.Size + 20 + Amount.ToByteArray().GetVarSize();

public override void Serialize(BinaryWriter writer)
{
base.Serialize(writer);
writer.Write(UserScriptHash);
writer.Write(BlockIndex);
writer.Write(TxHash);
writer.WriteVarBytes(Amount.ToByteArray());
}

public override void Deserialize(BinaryReader reader)
{
base.Deserialize(reader);
UserScriptHash = reader.ReadSerializable<UInt160>();
BlockIndex = reader.ReadUInt32();
TxHash = reader.ReadSerializable<UInt256>();
Amount = new BigInteger(reader.ReadVarBytes(512));
}

public Nep5Transfer Clone()
{
return new Nep5Transfer
{
UserScriptHash = UserScriptHash,
BlockIndex = BlockIndex,
TxHash = TxHash,
Amount = Amount
};
}

public void FromReplica(Nep5Transfer replica)
{
UserScriptHash = replica.UserScriptHash;
BlockIndex = replica.BlockIndex;
TxHash = replica.TxHash;
Amount = replica.Amount;
}
}
}
85 changes: 85 additions & 0 deletions RpcNep5Balances/Nep5TransferKey.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
using System;
using System.IO;
using Neo.IO;

namespace Neo.Plugins
{
public class Nep5TransferKey : IComparable<Nep5TransferKey>, IEquatable<Nep5TransferKey>, ISerializable
{
public readonly UInt160 UserScriptHash;
public uint Timestamp { get; private set; }
public readonly UInt160 AssetScriptHash;
public ushort BlockXferNotificationIndex { get; private set; }

public Nep5TransferKey() : this(new UInt160(), 0, new UInt160(), 0)
{
}

public Nep5TransferKey(UInt160 userScriptHash, uint timestamp, UInt160 assetScriptHash, ushort xferIndex)
{
if (userScriptHash is null || assetScriptHash is null)
throw new ArgumentNullException();
UserScriptHash = userScriptHash;
Timestamp = timestamp;
AssetScriptHash = assetScriptHash;
BlockXferNotificationIndex = xferIndex;
}

public int CompareTo(Nep5TransferKey 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 = Timestamp.CompareTo(other.Timestamp);
if (result2 != 0) return result2;
int result3 = AssetScriptHash.CompareTo(other.AssetScriptHash);
if (result3 != 0) return result3;
return BlockXferNotificationIndex.CompareTo(other.BlockXferNotificationIndex);
}

public bool Equals(Nep5TransferKey other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return UserScriptHash.Equals(other.UserScriptHash)
&& Timestamp.Equals(other.Timestamp) && AssetScriptHash.Equals(other.AssetScriptHash)
&& BlockXferNotificationIndex.Equals(other.BlockXferNotificationIndex);
}

public override bool Equals(Object other)
{
return other is Nep5TransferKey otherKey && Equals(otherKey);
}

public override int GetHashCode()
{
unchecked
{
var hashCode = UserScriptHash.GetHashCode();
hashCode = (hashCode * 397) ^ Timestamp.GetHashCode();
hashCode = (hashCode * 397) ^ AssetScriptHash.GetHashCode();
hashCode = (hashCode * 397) ^ BlockXferNotificationIndex.GetHashCode();
return hashCode;
}
}

public void Serialize(BinaryWriter writer)
{
writer.Write(UserScriptHash);
writer.Write(Timestamp);
writer.Write(AssetScriptHash);
writer.Write(BlockXferNotificationIndex);
}

public void Deserialize(BinaryReader reader)
{
((ISerializable) UserScriptHash).Deserialize(reader);
Timestamp = reader.ReadUInt32();
((ISerializable) AssetScriptHash).Deserialize(reader);
BlockXferNotificationIndex = reader.ReadUInt16();
}

public int Size { get; } = 20 + sizeof(byte) + sizeof(uint) + 20 + sizeof(ushort);
}
}
Loading