[C#] Add some initial C# tests
authorMatt Corallo <git@bluematt.me>
Tue, 7 Nov 2023 23:26:33 +0000 (23:26 +0000)
committerMatt Corallo <git@bluematt.me>
Fri, 10 Nov 2023 02:15:22 +0000 (02:15 +0000)
c_sharp/test/src/tests.cs [new file with mode: 0644]

diff --git a/c_sharp/test/src/tests.cs b/c_sharp/test/src/tests.cs
new file mode 100644 (file)
index 0000000..e27160c
--- /dev/null
@@ -0,0 +1,224 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using org.ldk.enums;
+using org.ldk.util;
+using org.ldk.structs;
+
+namespace tests {
+       static class Tests {
+               static void Assert(bool a, int assertion) {
+                       if (!a) {
+                               Console.WriteLine("Assertion " + assertion + " failed at");
+                               Console.WriteLine(new StackTrace().ToString());
+                               Environment.Exit(45);
+                       }
+               }
+
+               static void SimpleConstructionTest() {
+                       Ping ping = Ping.of(42, 43);
+                       Assert(ping.get_ponglen() == 42, 0);
+               }
+
+               class TestBroadcaster : BroadcasterInterfaceInterface {
+                       public bool broadcasted = false;
+                       public void broadcast_transactions(byte[][] txn) {
+                               Assert(txn.Length == 1, 1);
+                               Assert(txn[0].Length == 42, 2);
+                               broadcasted = true;
+                       }
+               }
+
+               static void SimpleTraitTest() {
+                       TestBroadcaster impl = new TestBroadcaster();
+                       BroadcasterInterface broadcaster = BroadcasterInterface.new_impl(impl);
+                       byte[][] txn = new byte[1][];
+                       txn[0] = new byte[42];
+                       broadcaster.broadcast_transactions(txn);
+                       Assert(impl.broadcasted == true, 3);
+               }
+
+               class TestEstimator : FeeEstimatorInterface {
+                       public int get_est_sat_per_1000_weight(ConfirmationTarget confirmation_target) {
+                               if (confirmation_target == ConfirmationTarget.LDKConfirmationTarget_MinAllowedNonAnchorChannelRemoteFee) {
+                                       return 253;
+                               } else {
+                                       return 300;
+                               }
+                       }
+               }
+
+               class TestLogger : LoggerInterface {
+                       public void log(Record record) {
+                               Console.WriteLine(record.get_module_path() + ":" + record.get_line() + " " + record.get_args());
+                       }
+               }
+
+               class TestPersister : PersistInterface {
+                       public ChannelMonitorUpdateStatus persist_new_channel(OutPoint channel_id, ChannelMonitor data, MonitorUpdateId update_id) {
+                               return ChannelMonitorUpdateStatus.LDKChannelMonitorUpdateStatus_Completed;
+                       }
+                       public ChannelMonitorUpdateStatus update_persisted_channel(OutPoint channel_id, ChannelMonitorUpdate update, ChannelMonitor data, MonitorUpdateId update_id) {
+                               return ChannelMonitorUpdateStatus.LDKChannelMonitorUpdateStatus_Completed;
+                       }
+               }
+
+               class TestEventHandler : EventHandlerInterface {
+                       public List<Event> events = new List<Event>();
+                       public void handle_event(Event ev) {
+                               events.Add(ev);
+                       }
+               }
+               static Event get_event(ChannelManager manager) {
+                       TestEventHandler impl = new TestEventHandler();
+                       org.ldk.structs.EventHandler handler = org.ldk.structs.EventHandler.new_impl(impl);
+                       manager.as_EventsProvider().process_pending_events(handler);
+                       Assert(impl.events.Count == 1, 100);
+                       return impl.events[0];
+               }
+
+               class Node {
+                       public BroadcasterInterface broadcaster = BroadcasterInterface.new_impl(new TestBroadcaster());
+                       public FeeEstimator estimator = FeeEstimator.new_impl(new TestEstimator());
+                       public Logger logger = Logger.new_impl(new TestLogger());
+                       public Persist persister = Persist.new_impl(new TestPersister());
+                       public ChainParameters chain_params = ChainParameters.of(Network.LDKNetwork_Bitcoin, BestBlock.from_network(Network.LDKNetwork_Bitcoin));
+
+                       public ChainMonitor chain_monitor;
+                       public NetworkGraph graph;
+                       public MultiThreadedLockableScore scorer;
+                       public DefaultRouter router;
+                       public KeysManager keys;
+                       public ChannelManager manager;
+
+                       public Node(byte seed) {
+                               chain_monitor = ChainMonitor.of(Option_FilterZ.none(), broadcaster, logger, estimator, persister);
+                               graph = NetworkGraph.of(Network.LDKNetwork_Bitcoin, logger);
+                               scorer = MultiThreadedLockableScore.of(ProbabilisticScorer.of(ProbabilisticScoringDecayParameters.with_default(), graph, logger).as_Score());
+                               router = DefaultRouter.of(graph, logger, new byte[32], scorer.as_LockableScore(), ProbabilisticScoringFeeParameters.with_default());
+
+                               byte[] seed_bytes = new byte[32];
+                               for (int i = 0; i < 32; i++) seed_bytes[i] = seed;
+                               keys = KeysManager.of(seed_bytes, 42, 43);
+
+                               manager = ChannelManager.of(estimator, chain_monitor.as_Watch(), broadcaster, router.as_Router(), logger, keys.as_EntropySource(), keys.as_NodeSigner(), keys.as_SignerProvider(), UserConfig.with_default(), chain_params, 42);
+                       }
+               }
+
+               static void NodeTest() {
+                       Node node_a = new Node(1);
+                       Node node_b = new Node(2);
+
+                       InitFeatures init_features = node_a.manager.as_ChannelMessageHandler().provided_init_features(node_b.manager.get_our_node_id());
+                       Init init_msg = Init.of(init_features, Option_CVec_ThirtyTwoBytesZZ.none(), Option_SocketAddressZ.none());
+                       node_a.manager.as_ChannelMessageHandler().peer_connected(node_b.manager.get_our_node_id(), init_msg, false);
+                       node_b.manager.as_ChannelMessageHandler().peer_connected(node_a.manager.get_our_node_id(), init_msg, false);
+
+                       Result_ThirtyTwoBytesAPIErrorZ res = node_a.manager.create_channel(node_b.manager.get_our_node_id(), 100000, 42, new UInt128(43), UserConfig.with_default());
+                       Assert(res.is_ok(), 4);
+
+                       MessageSendEvent[] msgs = node_a.manager.as_MessageSendEventsProvider().get_and_clear_pending_msg_events();
+                       Assert(msgs.Length == 1, 5);
+                       Assert(msgs[0] is MessageSendEvent.MessageSendEvent_SendOpenChannel, 6);
+                       node_b.manager.as_ChannelMessageHandler().handle_open_channel(node_a.manager.get_our_node_id(), ((MessageSendEvent.MessageSendEvent_SendOpenChannel) msgs[0]).msg);
+
+                       MessageSendEvent[] response_msgs = node_b.manager.as_MessageSendEventsProvider().get_and_clear_pending_msg_events();
+                       Assert(response_msgs.Length == 1, 7);
+                       Assert(response_msgs[0] is MessageSendEvent.MessageSendEvent_SendAcceptChannel, 8);
+                       node_a.manager.as_ChannelMessageHandler().handle_accept_channel(node_b.manager.get_our_node_id(), ((MessageSendEvent.MessageSendEvent_SendAcceptChannel) response_msgs[0]).msg);
+
+                       Event funding_ready = get_event(node_a.manager);
+                       Assert(funding_ready is Event.Event_FundingGenerationReady, 9);
+
+                       // We could use funding_transaction_generated here, but test batching
+                       TwoTuple_ThirtyTwoBytesPublicKeyZ[] channel = new TwoTuple_ThirtyTwoBytesPublicKeyZ[1];
+                       channel[0] = TwoTuple_ThirtyTwoBytesPublicKeyZ.of(((Event.Event_FundingGenerationReady) funding_ready).temporary_channel_id, ((Event.Event_FundingGenerationReady) funding_ready).counterparty_node_id);
+
+                       // Hand-crafted transaction which has a dummy witness and can pay to our script
+                       byte[] transaction = new byte[99];
+                       transaction[0] = 2;
+                       transaction[1] = 0;
+                       transaction[2] = 0;
+                       transaction[3] = 0;
+                       transaction[4] = 0;
+                       transaction[5] = 1;
+                       transaction[6] = 1;
+                       transaction[7] = 66;
+                       transaction[8] = 66;
+                       transaction[9] = 66;
+                       transaction[10] = 66;
+                       transaction[11] = 66;
+                       transaction[12] = 66;
+                       transaction[13] = 66;
+                       transaction[14] = 66;
+                       transaction[15] = 66;
+                       transaction[16] = 66;
+                       transaction[17] = 66;
+                       transaction[18] = 66;
+                       transaction[19] = 66;
+                       transaction[20] = 66;
+                       transaction[21] = 66;
+                       transaction[22] = 66;
+                       transaction[23] = 66;
+                       transaction[24] = 66;
+                       transaction[25] = 66;
+                       transaction[26] = 66;
+                       transaction[27] = 66;
+                       transaction[28] = 66;
+                       transaction[29] = 66;
+                       transaction[30] = 66;
+                       transaction[31] = 66;
+                       transaction[32] = 66;
+                       transaction[33] = 66;
+                       transaction[34] = 66;
+                       transaction[35] = 66;
+                       transaction[36] = 66;
+                       transaction[37] = 66;
+                       transaction[38] = 66;
+                       transaction[39] = 18;
+                       transaction[40] = 0;
+                       transaction[41] = 0;
+                       transaction[42] = 0;
+                       transaction[43] = 0;
+                       transaction[44] = 253;
+                       transaction[45] = 255;
+                       transaction[46] = 255;
+                       transaction[47] = 255;
+                       transaction[48] = 1;
+                       transaction[49] = 34;
+                       transaction[50] = 2;
+                       transaction[51] = 0;
+                       transaction[52] = 0;
+                       transaction[53] = 0;
+                       transaction[54] = 0;
+                       transaction[55] = 0;
+                       transaction[56] = 0;
+                       transaction[57] = 34;
+
+                       Assert(((Event.Event_FundingGenerationReady) funding_ready).output_script.Length == 34, 10);
+                       for (int i = 0; i < 34; i++) {
+                               transaction[58 + i] = ((Event.Event_FundingGenerationReady) funding_ready).output_script[i];
+                       }
+
+                       transaction[92] = 1;
+                       transaction[93] = 1;
+                       transaction[94] = 1;
+                       transaction[95] = 0;
+                       transaction[96] = 0;
+                       transaction[97] = 0;
+                       transaction[98] = 0;
+
+                       node_a.manager.batch_funding_transaction_generated(channel, transaction);
+               }
+
+               static void Main(string[] args) {
+                       SimpleConstructionTest();
+                       SimpleTraitTest();
+                       NodeTest();
+
+                       Console.WriteLine("\n\nTESTS PASSED\n\n");
+                       System.GC.Collect();
+                       GC.WaitForPendingFinalizers();
+               }
+       }
+}