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 debug mode to the applicationlog to get log info #842

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 40 additions & 2 deletions src/ApplicationLogs/LogReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@ namespace Neo.Plugins
{
public class LogReader : Plugin
{
private IStore _db;
private ISnapshot _snapshot;
private static IStore _db;
private static ISnapshot _snapshot;
private static readonly byte[] LogPrefix = { 0x12 };

public override string Name => "ApplicationLogs";
public override string Description => "Synchronizes the smart contract log with the NativeContract log (Notify)";
Expand All @@ -34,12 +35,16 @@ public LogReader()
{
Blockchain.Committing += OnCommitting;
Blockchain.Committed += OnCommitted;
if (Settings.Default.Debug)
ApplicationEngine.Log += ApplicationEngine_Log;
Comment on lines +38 to +39
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a nice feature. How about adding the same ability to add logs to execution result for invokescript, invokefunction and etc. in debug mode? This change is more invasive and requires changing the core library as far, but it might be useful for someone.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

}

public override void Dispose()
{
Blockchain.Committing -= OnCommitting;
Blockchain.Committed -= OnCommitted;
if (Settings.Default.Debug)
ApplicationEngine.Log -= ApplicationEngine_Log;
}

protected override void Configure()
Expand Down Expand Up @@ -76,6 +81,12 @@ public JToken GetApplicationLog(JArray _params)
i++;
}
}
if (!Settings.Default.Debug) return raw;
byte[] logs = _db.TryGet(LogPrefix.Concat(hash.ToArray()).ToArray());
if (logs != null)
{
raw["executions"]["logs"] = (JArray)JToken.Parse(Neo.Utility.StrictUTF8.GetString(value));
}
return raw;
}

Expand Down Expand Up @@ -186,6 +197,33 @@ private void OnCommitting(NeoSystem system, Block block, DataCache snapshot, IRe
}
}

private static void ApplicationEngine_Log(object sender, LogEventArgs args)
{
if (!Settings.Default.Debug) return;

var tx = ((Transaction)args.ScriptContainer).Hash;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It can be not only a transaction, right? E.g. block for OnPersist and PostPersist execution results.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It can be not only a transaction, right? E.g. block for OnPersist and PostPersist execution results.

I think it can only be transaction, but i might be wrong. May you please confirm @shargon @roman-khimov


byte[] value = _db.TryGet(LogPrefix.Concat(tx.ToArray()).ToArray());

JArray logList = null;
if (value is null)
{
logList = new JArray();
}
else
{
logList = (JArray)JToken.Parse(Neo.Utility.StrictUTF8.GetString(value));
}
var logJson = new JObject
{
["contract"] = args.ScriptHash.ToString(),
["message"] = args.Message
};
logList?.Add(logJson);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you need ? here? logList is always non-null.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you need ? here? logList is always non-null.

It is possible since in the else block, the assignment might be null.


_snapshot.Put(LogPrefix.Concat(tx.ToArray()).ToArray(), Neo.Utility.StrictUTF8.GetBytes(logList?.ToString()!));
}

private void OnCommitted(NeoSystem system, Block block)
{
if (system.Settings.Network != Settings.Default.Network) return;
Expand Down
3 changes: 3 additions & 0 deletions src/ApplicationLogs/Settings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,16 @@ internal class Settings
public uint Network { get; }
public int MaxStackSize { get; }

public bool Debug { get; }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we planning to enable this setting in public networks?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could, after solid test and monorepo. but now this is only to answer the need of @cschuchardt88 on neo-express.


public static Settings Default { get; private set; }

private Settings(IConfigurationSection section)
{
this.Path = section.GetValue("Path", "ApplicationLogs_{0}");
this.Network = section.GetValue("Network", 5195086u);
this.MaxStackSize = section.GetValue("MaxStackSize", (int)ushort.MaxValue);
this.Debug = section.GetValue("Debug", false);
}

public static void Load(IConfigurationSection section)
Expand Down
3 changes: 2 additions & 1 deletion src/ApplicationLogs/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
"PluginConfiguration": {
"Path": "ApplicationLogs_{0}",
"Network": 860833102,
"MaxStackSize": 65535
"MaxStackSize": 65535,
"Debug": false
},
"Dependency": [
"RpcServer"
Expand Down
35 changes: 34 additions & 1 deletion src/RpcClient/Models/RpcApplicationLog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ public class Execution

public List<RpcNotifyEventArgs> Notifications { get; set; }

public List<RpcLogEventArgs> Logs { get; set; }

public JObject ToJson()
{
JObject json = new();
Expand All @@ -70,6 +72,11 @@ public JObject ToJson()
json["exception"] = ExceptionMessage;
json["stack"] = Stack.Select(q => q.ToJson()).ToArray();
json["notifications"] = Notifications.Select(q => q.ToJson()).ToArray();
// Only add "logs" to json if Logs is not null
if (Logs != null)
{
json["logs"] = Logs.Select(q => q.ToJson()).ToArray();
}
return json;
}

Expand All @@ -82,7 +89,8 @@ public static Execution FromJson(JObject json, ProtocolSettings protocolSettings
GasConsumed = long.Parse(json["gasconsumed"].AsString()),
ExceptionMessage = json["exception"]?.AsString(),
Stack = ((JArray)json["stack"]).Select(p => Utility.StackItemFromJson((JObject)p)).ToList(),
Notifications = ((JArray)json["notifications"]).Select(p => RpcNotifyEventArgs.FromJson((JObject)p, protocolSettings)).ToList()
Notifications = ((JArray)json["notifications"]).Select(p => RpcNotifyEventArgs.FromJson((JObject)p, protocolSettings)).ToList(),
Logs = ((JArray)json["logs"])?.Select(p => RpcLogEventArgs.FromJson((JObject)p, protocolSettings)).ToList()
};
}
}
Expand Down Expand Up @@ -114,4 +122,29 @@ public static RpcNotifyEventArgs FromJson(JObject json, ProtocolSettings protoco
};
}
}

public class RpcLogEventArgs
{
public UInt160 Contract { get; set; }

public string Message { get; set; }

public JObject ToJson()
{
return new JObject
{
["contract"] = Contract.ToString(),
["message"] = Message
};
}

public static RpcLogEventArgs FromJson(JObject json, ProtocolSettings protocolSettings)
{
return new RpcLogEventArgs
{
Contract = json["contract"].ToScriptHash(protocolSettings),
Message = json["message"]?.AsString(),
};
}
}
}