diff --git a/Substrate.NetApi.Test/Substrate.NetApi.Test.csproj b/Substrate.NetApi.Test/Substrate.NetApi.Test.csproj
index 017d6a9..f95e7f8 100644
--- a/Substrate.NetApi.Test/Substrate.NetApi.Test.csproj
+++ b/Substrate.NetApi.Test/Substrate.NetApi.Test.csproj
@@ -8,8 +8,8 @@
-
-
+
+
diff --git a/Substrate.NetApi.TestNode/BasicTest.cs b/Substrate.NetApi.TestNode/BasicTest.cs
index dea3f99..9258788 100644
--- a/Substrate.NetApi.TestNode/BasicTest.cs
+++ b/Substrate.NetApi.TestNode/BasicTest.cs
@@ -145,38 +145,6 @@ public async Task GetBlocknumberAtBlockHashTestAsync()
Assert.AreEqual(currentBlocknumber.Value, result.Value);
}
- ///
- /// Simple extrinsic tester
- ///
- ///
- ///
- private static void ActionExtrinsicUpdate(string subscriptionId, ExtrinsicStatus extrinsicUpdate)
- {
- switch (extrinsicUpdate.ExtrinsicState)
- {
- case ExtrinsicState.None:
- Assert.IsTrue(true);
- Assert.IsTrue(extrinsicUpdate.InBlock.Value.Length > 0 || extrinsicUpdate.Finalized.Value.Length > 0);
- break;
-
- case ExtrinsicState.Future:
- Assert.IsTrue(false);
- break;
-
- case ExtrinsicState.Ready:
- Assert.IsTrue(true);
- break;
-
- case ExtrinsicState.Dropped:
- Assert.IsTrue(false);
- break;
-
- case ExtrinsicState.Invalid:
- Assert.IsTrue(false);
- break;
- }
- }
-
///
/// >> 1 - Array
///
diff --git a/Substrate.NetApi.TestNode/ExtrinsicsTest.cs b/Substrate.NetApi.TestNode/ExtrinsicsTest.cs
new file mode 100644
index 0000000..9bba304
--- /dev/null
+++ b/Substrate.NetApi.TestNode/ExtrinsicsTest.cs
@@ -0,0 +1,148 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Substrate.NetApi.Model.Extrinsics;
+using Substrate.NetApi.Model.Rpc;
+using Substrate.NetApi.Model.Types;
+using Substrate.NetApi.Model.Types.Base;
+using Substrate.NetApi.Model.Types.Primitive;
+using NUnit.Framework;
+using Schnorrkel.Keys;
+
+namespace Substrate.NetApi.TestNode
+{
+ public class ExtrinsicsTest
+ {
+ public MiniSecret MiniSecretAlice => new MiniSecret(Utils.HexToByteArray("0xe5be9a5092b81bca64be81d212e7f2f9eba183bb7a90954f7b76361f6edb5c0a"), ExpandMode.Ed25519);
+ public Account Alice => Account.Build(KeyType.Sr25519, MiniSecretAlice.ExpandToSecret().ToBytes(), MiniSecretAlice.GetPair().Public.Key);
+ public MiniSecret MiniSecretBob => new MiniSecret(Utils.HexToByteArray("0x398f0c28f98885e046333d4a41c19cee4c37368a9832c6502f6cfd182e2aef89"), ExpandMode.Ed25519);
+ public Account Bob => Account.Build(KeyType.Sr25519, MiniSecretBob.ExpandToSecret().ToBytes(), MiniSecretBob.GetPair().Public.Key);
+
+ protected const string WebSocketUrl = "ws://127.0.0.1:9944";
+
+ protected SubstrateClient _substrateClient;
+
+ protected ChargeType _chargeType;
+
+ [SetUp]
+ public async Task ConnectAsync()
+ {
+ await _substrateClient.ConnectAsync();
+ }
+
+ [TearDown]
+ public async Task CloseAsync()
+ {
+ await _substrateClient.CloseAsync();
+ }
+
+ [OneTimeSetUp]
+ public void CreateClient()
+ {
+ _chargeType = ChargeAssetTxPayment.Default();
+ _substrateClient = new SubstrateClient(new Uri(WebSocketUrl), _chargeType);
+ }
+
+ [OneTimeTearDown]
+ public void DisposeClient()
+ {
+ _substrateClient.Dispose();
+ }
+
+ ///
+ /// Extrinsic Remark test
+ ///
+ ///
+ [Test]
+ public async Task Extrinsic_RemarkAsync()
+ {
+ var method = new Method(0, "System", 0, "remark", new byte[] { 0x04, 0xFF });
+
+ var taskCompletionSource = new TaskCompletionSource();
+ await _substrateClient.Author.SubmitAndWatchExtrinsicAsync((string subscriptionId, ExtrinsicStatus extrinsicUpdate) => Callback(subscriptionId, extrinsicUpdate, taskCompletionSource), method, Alice, _chargeType, 64, CancellationToken.None);
+
+ var finished = await Task.WhenAny(taskCompletionSource.Task, Task.Delay(TimeSpan.FromMinutes(1))); // 5 minutes or any appropriate timeout
+ Assert.AreEqual(taskCompletionSource.Task, finished, "Test timed out waiting for final callback");
+ }
+
+ ///
+ /// Extrinsic Transfer Callback test
+ ///
+ ///
+ ///
+ ///
+ private static void Callback(string subscriptionId, ExtrinsicStatus extrinsicUpdate, TaskCompletionSource taskCompletionSource)
+ {
+ ActionExtrinsicUpdate(subscriptionId, extrinsicUpdate);
+ if (extrinsicUpdate.ExtrinsicState == ExtrinsicState.Finalized ||
+ extrinsicUpdate.ExtrinsicState == ExtrinsicState.Dropped ||
+ extrinsicUpdate.ExtrinsicState == ExtrinsicState.Invalid)
+ {
+ taskCompletionSource.SetResult(true);
+ }
+ }
+
+ ///
+ /// Simple extrinsic tester
+ ///
+ ///
+ ///
+ private static void ActionExtrinsicUpdate(string subscriptionId, ExtrinsicStatus extrinsicUpdate)
+ {
+ if (subscriptionId == null || subscriptionId.Length == 0)
+ {
+ Assert.IsTrue(false);
+ }
+
+ switch (extrinsicUpdate.ExtrinsicState)
+ {
+ case ExtrinsicState.Future:
+ Assert.IsTrue(false);
+ break;
+
+ case ExtrinsicState.Ready:
+ Assert.IsTrue(true);
+ break;
+
+ case ExtrinsicState.Dropped:
+ Assert.IsTrue(false);
+ break;
+
+ case ExtrinsicState.Invalid:
+ Assert.IsTrue(false);
+ break;
+
+ case ExtrinsicState.Broadcast:
+ Assert.IsTrue(extrinsicUpdate.Broadcast != null);
+ break;
+
+ case ExtrinsicState.InBlock:
+ Assert.IsTrue(extrinsicUpdate.Hash.Value.Length > 0);
+ break;
+
+ case ExtrinsicState.Retracted:
+ Assert.IsTrue(extrinsicUpdate.Hash.Value.Length > 0);
+ break;
+
+ case ExtrinsicState.FinalityTimeout:
+ Assert.IsTrue(extrinsicUpdate.Hash.Value.Length > 0);
+ break;
+
+ case ExtrinsicState.Finalized:
+ Assert.IsTrue(extrinsicUpdate.Hash.Value.Length > 0);
+ break;
+
+ case ExtrinsicState.Usurped:
+ Assert.IsTrue(extrinsicUpdate.Hash.Value.Length > 0);
+ break;
+
+ default:
+ Assert.IsTrue(false);
+ break;
+
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Substrate.NetApi.TestNode/QueryAllTest.cs b/Substrate.NetApi.TestNode/QueryAllTest.cs
index 3886b46..ebc5988 100644
--- a/Substrate.NetApi.TestNode/QueryAllTest.cs
+++ b/Substrate.NetApi.TestNode/QueryAllTest.cs
@@ -1,21 +1,18 @@
-using Substrate.NetApi.Model.Extrinsics;
-using NUnit.Framework;
+using NUnit.Framework;
+using Substrate.NetApi.Model.Types;
+using Substrate.NetApi.Model.Types.Base;
+using Substrate.NetApi.Model.Types.Primitive;
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
using System.Threading;
-using Substrate.NetApi.Model.Types.Base;
-using Substrate.NetApi.Model.Types.Primitive;
-using Substrate.NetApi.Model.Types;
-using System.Diagnostics;
+using System.Threading.Tasks;
namespace Substrate.NetApi.TestNode
{
public class QueryAllTest : NodeTest
{
-
[Test]
public async Task GetAllStorageTestAsync()
{
@@ -43,10 +40,10 @@ public async Task GetAllStorageTestAsync()
Assert.IsNotNull(allPages);
Assert.AreNotEqual(0, allPages.Count);
- Assert.Greater(10000, stopwatch.ElapsedMilliseconds, "Get all storage did use more then 10 sec., verify!");
+ Assert.Greater(20000, stopwatch.ElapsedMilliseconds, "Get all storage did use more then 10 sec., verify!");
}
- public async Task> GetAllStoragePagedAsync(string module, string item, byte[] startKey, uint page, string blockHash, CancellationToken token)
+ public async Task> GetAllStoragePagedAsync(string module, string item, byte[] startKey, uint page, string blockHash, CancellationToken token)
where T1 : IType, new()
where T2 : IType, new()
{
@@ -250,4 +247,4 @@ public void Create(U8[] array)
Bytes = Encode();
}
}
-}
+}
\ No newline at end of file
diff --git a/Substrate.NetApi.TestNode/Substrate.NetApi.TestNode.csproj b/Substrate.NetApi.TestNode/Substrate.NetApi.TestNode.csproj
index 3e90df7..846957e 100644
--- a/Substrate.NetApi.TestNode/Substrate.NetApi.TestNode.csproj
+++ b/Substrate.NetApi.TestNode/Substrate.NetApi.TestNode.csproj
@@ -7,10 +7,10 @@
-
+
-
-
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/Substrate.NetApi/Model/Extrinsics/Extrinsic.cs b/Substrate.NetApi/Model/Extrinsics/Extrinsic.cs
index 927714c..cd5b709 100644
--- a/Substrate.NetApi/Model/Extrinsics/Extrinsic.cs
+++ b/Substrate.NetApi/Model/Extrinsics/Extrinsic.cs
@@ -92,7 +92,7 @@ internal Extrinsic(Memory memory, ChargeType chargeType)
// nonce
Nonce = CompactInteger.Decode(memory.ToArray(), ref p);
- // chargeAssetTxPayment
+ // charge type
Charge = chargeType;
Charge.Decode(memory.ToArray(), ref p);
}
diff --git a/Substrate.NetApi/Model/Rpc/ExtrinsicStatus.cs b/Substrate.NetApi/Model/Rpc/ExtrinsicStatus.cs
index 512d70b..8a6b590 100644
--- a/Substrate.NetApi/Model/Rpc/ExtrinsicStatus.cs
+++ b/Substrate.NetApi/Model/Rpc/ExtrinsicStatus.cs
@@ -5,18 +5,18 @@ namespace Substrate.NetApi.Model.Rpc
{
public enum ExtrinsicState
{
- None, Future, Ready, Dropped, Invalid
+ Future, Ready, Broadcast, InBlock, Retracted, FinalityTimeout, Finalized, Usurped, Dropped, Invalid
}
public class ExtrinsicStatus
{
public ExtrinsicState ExtrinsicState { get; set; }
+
public string[] Broadcast { get; set; }
- public Hash InBlock { get; set; }
- public Hash Retracted { get; set; }
- public Hash FinalityTimeout { get; set; }
- public Hash Finalized { get; set; }
- public Hash Usurped { get; set; }
+
+ public Hash Hash { get; set; }
+
+ //public ulong? TxIndex { get; set; }
public override string ToString()
{
diff --git a/Substrate.NetApi/Substrate.NetApi.csproj b/Substrate.NetApi/Substrate.NetApi.csproj
index 24a4286..e2cf831 100644
--- a/Substrate.NetApi/Substrate.NetApi.csproj
+++ b/Substrate.NetApi/Substrate.NetApi.csproj
@@ -3,7 +3,7 @@
Substrate.NET.API
netstandard2.0;netstandard2.1;net6.0
- 0.9.9
+ 0.9.10
Substrate Gaming
Substrate Gaming
true
diff --git a/Substrate.NetApi/TypeConverters/ExtrinsicJsonConverter.cs b/Substrate.NetApi/TypeConverters/ExtrinsicJsonConverter.cs
index 1926da4..1925f79 100644
--- a/Substrate.NetApi/TypeConverters/ExtrinsicJsonConverter.cs
+++ b/Substrate.NetApi/TypeConverters/ExtrinsicJsonConverter.cs
@@ -1,19 +1,15 @@
-using System;
+using Newtonsoft.Json;
using Substrate.NetApi.Model.Extrinsics;
-using Newtonsoft.Json;
-using Serilog;
+using System;
namespace Substrate.NetApi.TypeConverters
{
///
- ///
+ /// Extrinsic Json Converter
///
internal class ExtrinsicJsonConverter : JsonConverter
{
- /// The logger.
- private static readonly ILogger Logger = new LoggerConfiguration().CreateLogger();
-
- private ChargeType _chargeType;
+ private readonly ChargeType _chargeType;
public ExtrinsicJsonConverter(ChargeType chargeType)
{
diff --git a/Substrate.NetApi/TypeConverters/ExtrinsicStatusJsonConverter.cs b/Substrate.NetApi/TypeConverters/ExtrinsicStatusJsonConverter.cs
index 36ec466..b365c03 100644
--- a/Substrate.NetApi/TypeConverters/ExtrinsicStatusJsonConverter.cs
+++ b/Substrate.NetApi/TypeConverters/ExtrinsicStatusJsonConverter.cs
@@ -1,8 +1,8 @@
-using System;
-using System.Collections.Generic;
+using Newtonsoft.Json;
using Substrate.NetApi.Model.Rpc;
using Substrate.NetApi.Model.Types.Base;
-using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
namespace Substrate.NetApi.TypeConverters
{
@@ -23,7 +23,7 @@ public class ExtrinsicStatusJsonConverter : JsonConverter
public override ExtrinsicStatus ReadJson(JsonReader reader, Type objectType, ExtrinsicStatus existingValue,
bool hasExistingValue, JsonSerializer serializer)
{
- var extrinsicStatus = new ExtrinsicStatus();
+ var extrinsicStatus = hasExistingValue ? existingValue : new ExtrinsicStatus();
if (reader.TokenType == JsonToken.String &&
Enum.TryParse((string)reader.Value, true, out ExtrinsicState extrinsicState))
@@ -32,82 +32,46 @@ public override ExtrinsicStatus ReadJson(JsonReader reader, Type objectType, Ext
}
else if (reader.TokenType == JsonToken.StartObject)
{
- reader.Read();
-
- while (reader.TokenType != JsonToken.EndObject)
+ while (reader.Read())
{
- switch (reader.TokenType)
- {
- case JsonToken.PropertyName:
-
- if (reader.ValueType == typeof(string))
- switch (reader.Value)
- {
- case "broadcast":
- reader.Read();
- if (reader.TokenType == JsonToken.StartArray)
- {
- var broadcastList = new List();
- while (reader.TokenType != JsonToken.EndArray)
- {
- if (reader.ValueType == typeof(string))
- broadcastList.Add((string)reader.Value);
- reader.Read();
- }
-
- extrinsicStatus.Broadcast = broadcastList.ToArray();
- }
-
- break;
-
- case "inBlock":
- reader.Read();
- var inBlock = new Hash();
- inBlock.Create((string)reader.Value);
- extrinsicStatus.InBlock = inBlock;
- break;
+ if (reader.TokenType == JsonToken.EndObject)
+ break;
- case "finalized":
- reader.Read();
- var finalized = new Hash();
- finalized.Create((string)reader.Value);
- extrinsicStatus.Finalized = finalized;
- break;
-
- case "finalityTimeout":
- reader.Read();
- var finalityTimeout = new Hash();
- finalityTimeout.Create((string)reader.Value);
- extrinsicStatus.FinalityTimeout = finalityTimeout;
- break;
-
- case "retracted":
- reader.Read();
- var retracted = new Hash();
- retracted.Create((string)reader.Value);
- extrinsicStatus.Retracted = retracted;
- break;
-
- case "usurped":
- reader.Read();
- var usurped = new Hash();
- usurped.Create((string)reader.Value);
- extrinsicStatus.Usurped = usurped;
- break;
-
- default:
- throw new NotImplementedException(
- $"Unimplemented {reader.TokenType} of type '{reader.ValueType}' and value '{reader.Value}'.");
- }
-
- break;
-
- default:
- throw new NotImplementedException(
- $"Unimplemented {reader.TokenType} of type '{reader.ValueType}' and value '{reader.Value}'.");
+ if (reader.TokenType == JsonToken.PropertyName)
+ {
+ var propertyName = reader.Value.ToString();
+ if (Enum.TryParse(propertyName, true, out extrinsicState))
+ {
+ extrinsicStatus.ExtrinsicState = extrinsicState;
+ reader.Read();
+
+ switch (extrinsicState)
+ {
+ case ExtrinsicState.Broadcast:
+ var broadcastList = new List();
+ while (reader.Read() && reader.TokenType != JsonToken.EndArray)
+ {
+ if (reader.TokenType == JsonToken.String)
+ broadcastList.Add(reader.Value.ToString());
+ }
+ extrinsicStatus.Broadcast = broadcastList.ToArray();
+ break;
+
+ case ExtrinsicState.InBlock:
+ case ExtrinsicState.Finalized:
+ case ExtrinsicState.FinalityTimeout:
+ case ExtrinsicState.Retracted:
+ case ExtrinsicState.Usurped:
+ if (reader.TokenType == JsonToken.String)
+ extrinsicStatus.Hash = new Hash(reader.Value.ToString());
+ break;
+
+ default:
+ throw new NotImplementedException(
+ $"Unimplemented state {extrinsicState} with value '{reader.Value}'.");
+ }
+ }
}
-
- reader.Read();
}
}