From: Matt Corallo Date: Tue, 7 Nov 2023 23:26:33 +0000 (+0000) Subject: [C#] Add some initial C# tests X-Git-Tag: v0.0.118.0-alpha0~4 X-Git-Url: http://git.bitcoin.ninja/index.cgi?p=ldk-java;a=commitdiff_plain;h=d23f234d571cb3094e3b33f287d065877793361a [C#] Add some initial C# tests --- diff --git a/c_sharp/test/src/tests.cs b/c_sharp/test/src/tests.cs new file mode 100644 index 00000000..e27160cb --- /dev/null +++ b/c_sharp/test/src/tests.cs @@ -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 events = new List(); + 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(); + } + } +}