Skip to content

Commit

Permalink
Add event name to System.Runtime.Notify() (#1701)
Browse files Browse the repository at this point in the history
  • Loading branch information
erikzhang committed Jun 15, 2020
1 parent 7cb2939 commit b729f79
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 53 deletions.
10 changes: 6 additions & 4 deletions src/neo/SmartContract/ApplicationEngine.Runtime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ namespace Neo.SmartContract
{
partial class ApplicationEngine
{
public const int MaxEventName = 32;
public const int MaxNotificationSize = 1024;

public static readonly InteropDescriptor System_Runtime_Platform = Register("System.Runtime.Platform", nameof(GetPlatform), 0_00000250, TriggerType.All, CallFlags.None);
Expand Down Expand Up @@ -146,15 +147,16 @@ internal void RuntimeLog(byte[] state)
Log?.Invoke(this, new LogEventArgs(ScriptContainer, CurrentScriptHash, message));
}

internal void RuntimeNotify(StackItem state)
internal void RuntimeNotify(byte[] eventName, Array state)
{
if (eventName.Length > MaxEventName) throw new ArgumentException();
if (!CheckItemForNotification(state)) throw new ArgumentException();
SendNotification(CurrentScriptHash, state);
SendNotification(CurrentScriptHash, Encoding.UTF8.GetString(eventName), state);
}

internal void SendNotification(UInt160 script_hash, StackItem state)
internal void SendNotification(UInt160 hash, string eventName, Array state)
{
NotifyEventArgs notification = new NotifyEventArgs(ScriptContainer, script_hash, state);
NotifyEventArgs notification = new NotifyEventArgs(ScriptContainer, hash, eventName, state);
Notify?.Invoke(this, notification);
notifications.Add(notification);
}
Expand Down
6 changes: 3 additions & 3 deletions src/neo/SmartContract/Native/Tokens/Nep5Token.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ internal protected virtual void Mint(ApplicationEngine engine, UInt160 account,
BigInteger totalSupply = new BigInteger(storage.Value);
totalSupply += amount;
storage.Value = totalSupply.ToByteArrayStandard();
engine.SendNotification(Hash, new Array(new StackItem[] { "Transfer", StackItem.Null, account.ToArray(), amount }));
engine.SendNotification(Hash, "Transfer", new Array { StackItem.Null, account.ToArray(), amount });
}

internal protected virtual void Burn(ApplicationEngine engine, UInt160 account, BigInteger amount)
Expand All @@ -99,7 +99,7 @@ internal protected virtual void Burn(ApplicationEngine engine, UInt160 account,
BigInteger totalSupply = new BigInteger(storage.Value);
totalSupply -= amount;
storage.Value = totalSupply.ToByteArrayStandard();
engine.SendNotification(Hash, new Array(new StackItem[] { "Transfer", account.ToArray(), StackItem.Null, amount }));
engine.SendNotification(Hash, "Transfer", new Array { account.ToArray(), StackItem.Null, amount });
}

[ContractMethod(0_01000000, CallFlags.AllowStates)]
Expand Down Expand Up @@ -159,7 +159,7 @@ protected virtual bool Transfer(ApplicationEngine engine, UInt160 from, UInt160
state_to.Balance += amount;
}
}
engine.SendNotification(Hash, new Array(new StackItem[] { "Transfer", from.ToArray(), to.ToArray(), amount }));
engine.SendNotification(Hash, "Transfer", new Array { from.ToArray(), to.ToArray(), amount });
return true;
}

Expand Down
8 changes: 5 additions & 3 deletions src/neo/SmartContract/NotifyEventArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ public class NotifyEventArgs : EventArgs, IInteroperable
{
public IVerifiable ScriptContainer { get; }
public UInt160 ScriptHash { get; }
public StackItem State { get; }
public string EventName { get; }
public Array State { get; }

public NotifyEventArgs(IVerifiable container, UInt160 script_hash, StackItem state)
public NotifyEventArgs(IVerifiable container, UInt160 script_hash, string eventName, Array state)
{
this.ScriptContainer = container;
this.ScriptHash = script_hash;
this.EventName = eventName;
this.State = state;
}

Expand All @@ -27,7 +29,7 @@ public void FromStackItem(StackItem stackItem)

public StackItem ToStackItem(ReferenceCounter referenceCounter)
{
return new Array(referenceCounter, new[] { ScriptHash.ToArray(), State });
return new Array(referenceCounter) { ScriptHash.ToArray(), EventName, State };
}
}
}
27 changes: 13 additions & 14 deletions tests/neo.UnitTests/SmartContract/UT_ApplicationEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@
using Neo.Network.P2P.Payloads;
using Neo.Persistence;
using Neo.SmartContract;
using Neo.VM.Types;

namespace Neo.UnitTests.SmartContract
{
[TestClass]
public class UT_ApplicationEngine
{
private string message = null;
private StackItem item = null;
private string eventName = null;

[TestInitialize]
public void TestSetup()
Expand All @@ -28,23 +27,23 @@ public void TestNotify()
var snapshot = Blockchain.Singleton.GetSnapshot();
var engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true);
ApplicationEngine.Notify += Test_Notify1;
StackItem notifyItem = "TestItem";
const string notifyEvent = "TestEvent";

engine.SendNotification(UInt160.Zero, notifyItem);
item.Should().Be(notifyItem);
engine.SendNotification(UInt160.Zero, notifyEvent, null);
eventName.Should().Be(notifyEvent);

ApplicationEngine.Notify += Test_Notify2;
engine.SendNotification(UInt160.Zero, notifyItem);
item.Should().Be(null);
engine.SendNotification(UInt160.Zero, notifyEvent, null);
eventName.Should().Be(null);

item = notifyItem;
eventName = notifyEvent;
ApplicationEngine.Notify -= Test_Notify1;
engine.SendNotification(UInt160.Zero, notifyItem);
item.Should().Be(null);
engine.SendNotification(UInt160.Zero, notifyEvent, null);
eventName.Should().Be(null);

ApplicationEngine.Notify -= Test_Notify2;
engine.SendNotification(UInt160.Zero, notifyItem);
item.Should().Be(null);
engine.SendNotification(UInt160.Zero, notifyEvent, null);
eventName.Should().Be(null);
}

private void Test_Log1(object sender, LogEventArgs e)
Expand All @@ -59,12 +58,12 @@ private void Test_Log2(object sender, LogEventArgs e)

private void Test_Notify1(object sender, NotifyEventArgs e)
{
item = e.State;
eventName = e.EventName;
}

private void Test_Notify2(object sender, NotifyEventArgs e)
{
item = null;
eventName = null;
}

[TestMethod]
Expand Down
47 changes: 19 additions & 28 deletions tests/neo.UnitTests/SmartContract/UT_InteropService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,9 @@ public void Runtime_GetNotifications_Test()

using (var script = new ScriptBuilder())
{
// Drop arguments

script.Emit(OpCode.NIP);

// Notify method

script.Emit(OpCode.SWAP, OpCode.NEWARRAY, OpCode.SWAP);
script.EmitSysCall(ApplicationEngine.System_Runtime_Notify);

// Add return
Expand Down Expand Up @@ -81,14 +78,16 @@ public void Runtime_GetNotifications_Test()
using (var engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true))
using (var script = new ScriptBuilder())
{
// Notification 1 -> 13
// Notification

script.EmitPush(13);
script.EmitPush(0);
script.Emit(OpCode.NEWARRAY);
script.EmitPush("testEvent1");
script.EmitSysCall(ApplicationEngine.System_Runtime_Notify);

// Call script

script.EmitAppCall(scriptHash2, "test", 2, 1);
script.EmitAppCall(scriptHash2, "test", "testEvent2", 1);

// Drop return

Expand All @@ -114,31 +113,33 @@ public void Runtime_GetNotifications_Test()

// Check syscall result

AssertNotification(array[1], scriptHash2, 2);
AssertNotification(array[0], currentScriptHash, 13);
AssertNotification(array[1], scriptHash2, "testEvent2");
AssertNotification(array[0], currentScriptHash, "testEvent1");

// Check notifications

Assert.AreEqual(scriptHash2, engine.Notifications[1].ScriptHash);
Assert.AreEqual(2, engine.Notifications[1].State.GetBigInteger());
Assert.AreEqual("testEvent2", engine.Notifications[1].EventName);

Assert.AreEqual(currentScriptHash, engine.Notifications[0].ScriptHash);
Assert.AreEqual(13, engine.Notifications[0].State.GetBigInteger());
Assert.AreEqual("testEvent1", engine.Notifications[0].EventName);
}

// Script notifications

using (var engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true))
using (var script = new ScriptBuilder())
{
// Notification 1 -> 13
// Notification

script.EmitPush(13);
script.EmitPush(0);
script.Emit(OpCode.NEWARRAY);
script.EmitPush("testEvent1");
script.EmitSysCall(ApplicationEngine.System_Runtime_Notify);

// Call script

script.EmitAppCall(scriptHash2, "test", 2, 1);
script.EmitAppCall(scriptHash2, "test", "testEvent2", 1);

// Drop return

Expand All @@ -164,15 +165,15 @@ public void Runtime_GetNotifications_Test()

// Check syscall result

AssertNotification(array[0], scriptHash2, 2);
AssertNotification(array[0], scriptHash2, "testEvent2");

// Check notifications

Assert.AreEqual(scriptHash2, engine.Notifications[1].ScriptHash);
Assert.AreEqual(2, engine.Notifications[1].State.GetBigInteger());
Assert.AreEqual("testEvent2", engine.Notifications[1].EventName);

Assert.AreEqual(currentScriptHash, engine.Notifications[0].ScriptHash);
Assert.AreEqual(13, engine.Notifications[0].State.GetBigInteger());
Assert.AreEqual("testEvent1", engine.Notifications[0].EventName);
}

// Clean storage
Expand All @@ -185,21 +186,11 @@ private void AssertNotification(StackItem stackItem, UInt160 scriptHash, string
Assert.IsInstanceOfType(stackItem, typeof(VM.Types.Array));

var array = (VM.Types.Array)stackItem;
Assert.AreEqual(2, array.Count);
Assert.AreEqual(3, array.Count);
CollectionAssert.AreEqual(scriptHash.ToArray(), array[0].GetSpan().ToArray());
Assert.AreEqual(notification, array[1].GetString());
}

private void AssertNotification(StackItem stackItem, UInt160 scriptHash, int notification)
{
Assert.IsInstanceOfType(stackItem, typeof(VM.Types.Array));

var array = (VM.Types.Array)stackItem;
Assert.AreEqual(2, array.Count);
CollectionAssert.AreEqual(scriptHash.ToArray(), array[0].GetSpan().ToArray());
Assert.AreEqual(notification, array[1].GetBigInteger());
}

[TestMethod]
public void TestExecutionEngine_GetScriptContainer()
{
Expand Down
2 changes: 1 addition & 1 deletion tests/neo.UnitTests/SmartContract/UT_NotifyEventArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public void TestGetScriptContainer()
{
IVerifiable container = new TestVerifiable();
UInt160 script_hash = new byte[] { 0x00 }.ToScriptHash();
NotifyEventArgs args = new NotifyEventArgs(container, script_hash, 0);
NotifyEventArgs args = new NotifyEventArgs(container, script_hash, "Test", null);
args.ScriptContainer.Should().Be(container);
}
}
Expand Down

0 comments on commit b729f79

Please sign in to comment.