Skip to content

Commit

Permalink
Static types (#14)
Browse files Browse the repository at this point in the history
* first shot

* first shot

* checkpoint

* checkpoint

* well that works

* default data argument to null

* get rid of SendMessageCollection

* get_connection converted to static type

* make records init only

* lint

* update coverlet

* make get_block_chain_state statically type

* make BlockRecord methods statically typed

* convert to static types

* convert to static types

* convert to static types

* consistent naming

* Add Coin type

* lint

* add TrasnactionRecord and associated types

* add serialization tests

* ensure snake case serialization of json content

* wrap communciation failures in ResponseException

* lint

* static typing

* static type GetBlocks

* replace List<T> with IEnumerable<T>

* add UnfinishedHeaderBlock types

* add WalletInfo type

* add PoolState type

* CoinRecord

* Delete transactions.json

* ProperCase

* move chia types to sub-folder

* version bump

* replace IEnumerable with ICollection

* add DateTime helper properties

* fix get additions and removals

* check

* update to fix GetAdditionsAndRemovals test

* version bump

* ICollection

* commenta

* mempool start

* core mempoolitem serizilaer

* static types get_all_mempool_items

* Add ConvertList

* static types GetPuzzleAndSolution

* static types GetRecentSignagePoint

* static types GetRecentEOS

* lint

* nump version

* static type

* comments

* static types

* comments

* lint

* allow serivce names to be used for config endpoint

* ConvertList not ToObject

* cleaning up

* comments

* make AbsorbRewards static

* add TODOs for remaining dyanmic return types

* static types

* static types

* make static types

* static types

* static types

* fixing up tests

* test cleanup

* test cleanup

* test cleanup

* test cleanup

* alias Name as TransactionId

* test cleanup

* comments

* comments
  • Loading branch information
dkackman authored Aug 15, 2021
1 parent c0d56b6 commit 772df39
Show file tree
Hide file tree
Showing 64 changed files with 6,029 additions and 491 deletions.
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@ https://dkackman.github.io/chia-dotnet/

- Coverage of all of chia's rpc endpoints
- Daemon, Full Node, Farmer, Harvester Wallet, Plotter
- Complete coverage the methods at each endpoint
- Coverage of all of the methods at each endpoint
- as of 1.2.3 (if you find something missing please create an issue)
- Supports connecting via the `daemon` on `wss` or directly to each service over `https`
- both `https` and `wss` use tha same interfaces, so switching is seemless
- Static types for chia input and outputs
- Supports connecting via teh `daemon` on `wss` or directly to each service over `https`
- both `https` and `wss` use tha same interfaces so switching is seemless

### Examples

Expand All @@ -35,6 +36,7 @@ await daemon.RegisterService();

var fullNode = new FullNodeProxy(rpcClient, "unit_tests");
var state = await fullNode.GetBlockchainState(e);
Console.Log($"This node is synced: {state.Sync.Synced}")
```

#### Send me some chia
Expand Down Expand Up @@ -78,7 +80,7 @@ In addition to static vs dynamic typing, C# and Python have very different conve
- The chia RPC uses unsigned integers where dotnet might use signed. In cases where chia expects an unsigned number, it is unsigned on the dotnet side.
- `ulong` is used for the python 64 bit unsigned int.
- `BigInteger` is used for the python 128 bit unsigned int.
- Where the RPC return a scalar value, the dotnet code will as well.
- Where the RPC return a scalar value, the dotnet code will as well. If it is optional in python it will be `Nullable<T>` in dotnet
- Where the RPC returns a list of named scalar values, they are returned as a Tuple with named fields.
- Complex types and structs are currently returned as a `dynamic` [`ExpandoObject`](https://docs.microsoft.com/en-us/dotnet/api/system.dynamic.expandoobject?view=net-5.0). Static types are [coming soon](https://github.com/dkackman/chia-dotnet/discussions/13).
- Lists of things are returned as [`IEnumberable<T>`](https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.ienumerable-1?view=net-5.0).
Expand Down
3,623 changes: 3,623 additions & 0 deletions data.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions src/chia-dotnet.tests/ColouredCoinWalletTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ namespace chia.dotnet.tests
{
[TestClass]
[TestCategory("Integration")]
[Ignore("Needs a coloured coin wallet")]
public class ColouredCoinWalletTests
{
private static ColouredCoinWallet _theWallet;
Expand Down
11 changes: 7 additions & 4 deletions src/chia-dotnet.tests/DIDWalletTests.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
using System.Threading.Tasks;
using System.Threading;
using System.Threading.Tasks;

using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace chia.dotnet.tests
{
[TestClass]
[TestCategory("Integration")]
[Ignore]
[Ignore("Needs DID Wallet")]
public class DIDWalletTests
{
private static DIDWallet _theWallet;
Expand All @@ -17,7 +18,7 @@ public static async Task Initialize(TestContext context)
var rpcClient = Factory.CreateRpcClientFromHardcodedLocation();
await rpcClient.Connect();

var daemon = new DaemonProxy(rpcClient, "unit_tests");
var daemon = new DaemonProxy(rpcClient, "unit_tests");
await daemon.RegisterService();

var walletProxy = new WalletProxy(rpcClient, "unit_tests");
Expand All @@ -36,7 +37,9 @@ public static void ClassCleanup()
[TestMethod()]
public async Task GetPubKey()
{
var pubkey = await _theWallet.GetPubKey();
using var cts = new CancellationTokenSource(15000);

var pubkey = await _theWallet.GetPubKey(cts.Token);

Assert.IsNotNull(pubkey);
}
Expand Down
4 changes: 2 additions & 2 deletions src/chia-dotnet.tests/DaemonTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ namespace chia.dotnet.tests
/// </summary>
[TestClass]
[TestCategory("Integration")]
//[Ignore] // uncomment to suppress completely
public class DaemonTests
{
private static DaemonProxy _theDaemon;
Expand Down Expand Up @@ -53,10 +52,11 @@ public async Task GetHarvesterIsRunning()
}

[TestMethod]
[Ignore]
[Ignore("CAUTION")]
public async Task ExitDaemon()
{
using var cts = new CancellationTokenSource(15000);

await _theDaemon.Exit(cts.Token);

// if no exception the daemon was stopped successfully
Expand Down
41 changes: 31 additions & 10 deletions src/chia-dotnet.tests/DirectTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Threading;
using System.Threading.Tasks;

using Microsoft.VisualStudio.TestTools.UnitTesting;
Expand All @@ -10,42 +11,62 @@ public class DirectTests
{
[TestMethod]
[TestCategory("Integration")]
public async Task ConnectDirectlyToFullNode()
public async Task GetConnectionsDirect()
{
try
{
var endpoint = new EndpointInfo()
{
Uri = new Uri("https://172.26.210.216:8555"),
CertPath = @"\\wsl$/Ubuntu-20.04/home/don/.chia/mainnet/config/ssl/full_node/private_full_node.crt",
KeyPath = @"\\wsl$/Ubuntu-20.04/home/don/.chia/mainnet/config/ssl/full_node/private_full_node.key",
};
using var cts = new CancellationTokenSource(15000);

using var rpcClient = new HttpRpcClient(endpoint);
using var rpcClient = Factory.CreateDirectRpcClientFromHardcodedLocation(8555);
var fullNode = new FullNodeProxy(rpcClient, "unit_tests");

var state = await fullNode.GetBlockchainState();
var connections = await fullNode.GetConnections(cts.Token);

Assert.IsNotNull(connections);
}
catch (Exception e)
{
Assert.Fail(e.Message);
}
}

[TestMethod]
[TestCategory("Integration")]
public async Task GetBlockchainStateDirect()
{
try
{
using var cts = new CancellationTokenSource(15000);

using var rpcClient = Factory.CreateDirectRpcClientFromHardcodedLocation(8555);
var fullNode = new FullNodeProxy(rpcClient, "unit_tests");

var state = await fullNode.GetBlockchainState(cts.Token);

Assert.IsNotNull(state);
}
catch (Exception e)
{
Assert.Fail(e.Message);
}
}

[TestMethod]
[TestCategory("Integration")]
[Ignore]
public async Task ConnectDirectlyUsingConfigEndpoint()
{
try
{
var config = Config.Open();
var endpoint = config.GetEndpoint("full_node");

using var cts = new CancellationTokenSource(15000);

using var rpcClient = new HttpRpcClient(endpoint);
var fullNode = new FullNodeProxy(rpcClient, "unit_tests");

var state = await fullNode.GetBlockchainState();
var state = await fullNode.GetBlockchainState(cts.Token);
}
catch (Exception e)
{
Expand Down
33 changes: 29 additions & 4 deletions src/chia-dotnet.tests/Factory.cs
Original file line number Diff line number Diff line change
@@ -1,23 +1,48 @@
namespace chia.dotnet.tests
using System;

namespace chia.dotnet.tests
{
/// <summary>
/// Use this class to setup the connection to the daemon under test
/// </summary>
internal static class Factory
{
// this is the ip address of the chia node
private const string NodeHostAddress = "172.25.181.156";

public static HttpRpcClient CreateDirectRpcClientFromHardcodedLocation(int port)
{
var endpoint = new EndpointInfo()
{
Uri = new Uri($"https://{NodeHostAddress}:{port}"),
CertPath = @"\\wsl$/Ubuntu-20.04/home/don/.chia/mainnet/config/ssl/full_node/private_full_node.crt",
KeyPath = @"\\wsl$/Ubuntu-20.04/home/don/.chia/mainnet/config/ssl/full_node/private_full_node.key",
};

return new HttpRpcClient(endpoint);
}
/// <summary>
/// Create a daemon instance from a hardcoded address
/// Create a rpc client instance from a hardcoded address
/// </summary>
/// <returns><see cref="DaemonProxy"/></returns>
public static WebSocketRpcClient CreateRpcClientFromHardcodedLocation()
{
// this is an example using a WSL instance running locally
/*
# warning YOU MIGHT BE USING A PRODUCTION NODE
var endpoint = Config.Open().GetEndpoint("ui");
*/

///*
var endpoint = new EndpointInfo()
{
Uri = new System.Uri("wss://172.26.210.216:55400"),
Uri = new Uri($"wss://{NodeHostAddress}:55400"),
CertPath = @"\\wsl$/Ubuntu-20.04/home/don/.chia/mainnet/config/ssl/daemon/private_daemon.crt",
KeyPath = @"\\wsl$/Ubuntu-20.04/home/don/.chia/mainnet/config/ssl/daemon/private_daemon.key",
//Uri = new Uri("wss://localhost:55400"),
//CertPath = @"/home/don/.chia/mainnet/config/ssl/daemon/private_daemon.crt",
//KeyPath = @"/home/don/.chia/mainnet/config/ssl/daemon/private_daemon.key",
};
//*/
return new WebSocketRpcClient(endpoint);
}

Expand Down
58 changes: 52 additions & 6 deletions src/chia-dotnet.tests/FarmerProxyTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Threading;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

using Microsoft.VisualStudio.TestTools.UnitTesting;
Expand All @@ -10,7 +11,6 @@ namespace chia.dotnet.tests
/// </summary>
[TestClass]
[TestCategory("Integration")]
//[Ignore] // uncomment to suppress completely
public class FarmerProxyTests
{
private static FarmerProxy _theFarmer;
Expand All @@ -19,6 +19,7 @@ public class FarmerProxyTests
public static async Task Initialize(TestContext context)
{
using var cts = new CancellationTokenSource(15000);

var rpcClient = Factory.CreateRpcClientFromHardcodedLocation();
await rpcClient.Connect(cts.Token);

Expand Down Expand Up @@ -48,6 +49,7 @@ public async Task GetRewardTargets()

[TestMethod]
[TestCategory("CAUTION")]
[Ignore("CAUTION")]
public async Task SetRewardTargets()
{
using var cts = new CancellationTokenSource(15000);
Expand All @@ -64,16 +66,59 @@ public async Task GetSignagePoints()

var signagePoints = await _theFarmer.GetSignagePoints(cts.Token);

foreach (var sp in signagePoints)
{
if (sp.Proofs.Count() > 0)
{
System.Diagnostics.Debug.WriteLine("here");
}
}

Assert.IsNotNull(signagePoints);
}

[TestMethod]
[ExpectedException(typeof(ResponseException))]
public async Task GetSignagePoint()
{
using var cts = new CancellationTokenSource(15000);

_ = await _theFarmer.GetSignagePoint("fake", cts.Token);
var signagePoints = await _theFarmer.GetSignagePoints(cts.Token);
var spInfo = signagePoints.FirstOrDefault();
Assert.IsNotNull(spInfo);
var sp = await _theFarmer.GetSignagePoint(spInfo.SignagePoint.ChallengeChainSp, cts.Token);

Assert.IsNotNull(sp);
}

[TestMethod]
public async Task GetPoolState()
{
using var cts = new CancellationTokenSource(15000);

var state = await _theFarmer.GetPoolState(cts.Token);

Assert.IsNotNull(state);
}

[TestMethod]
public async Task GetPoolLoginLink()
{
using var cts = new CancellationTokenSource(15000);

var state = await _theFarmer.GetPoolState(cts.Token);
var pool = state.FirstOrDefault();
if (pool is not null)
{
Assert.IsNotNull(pool.PoolConfig);

var link = await _theFarmer.GetPoolLoginLink(pool.PoolConfig.LauncherId, cts.Token);

Assert.IsNotNull(link);
}
else
{
Assert.Inconclusive("This node isn't part of a pool");
}
}

[TestMethod]
Expand All @@ -82,6 +127,7 @@ public async Task GetHarvesters()
using var cts = new CancellationTokenSource(15000);

var harvesters = await _theFarmer.GetHarvesters(cts.Token);

Assert.IsNotNull(harvesters);
}

Expand All @@ -99,16 +145,16 @@ public async Task GetConnections()
using var cts = new CancellationTokenSource(15000);

var connections = await _theFarmer.GetConnections(cts.Token);

Assert.IsNotNull(connections);
}

[TestMethod]
[Ignore] // only works on mainnet
public async Task OpenConnection()
{
using var cts = new CancellationTokenSource(15000);

await _theFarmer.OpenConnection("node.chia.net", 8444, cts.Token);
await _theFarmer.OpenConnection("testnet-node.chia.net", 58444, cts.Token);
}
}
}
Loading

0 comments on commit 772df39

Please sign in to comment.