[C#] Add some initial C# tests
[ldk-java] / c_sharp / test / src / tests.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Diagnostics;
4 using org.ldk.enums;
5 using org.ldk.util;
6 using org.ldk.structs;
7
8 namespace tests {
9         static class Tests {
10                 static void Assert(bool a, int assertion) {
11                         if (!a) {
12                                 Console.WriteLine("Assertion " + assertion + " failed at");
13                                 Console.WriteLine(new StackTrace().ToString());
14                                 Environment.Exit(45);
15                         }
16                 }
17
18                 static void SimpleConstructionTest() {
19                         Ping ping = Ping.of(42, 43);
20                         Assert(ping.get_ponglen() == 42, 0);
21                 }
22
23                 class TestBroadcaster : BroadcasterInterfaceInterface {
24                         public bool broadcasted = false;
25                         public void broadcast_transactions(byte[][] txn) {
26                                 Assert(txn.Length == 1, 1);
27                                 Assert(txn[0].Length == 42, 2);
28                                 broadcasted = true;
29                         }
30                 }
31
32                 static void SimpleTraitTest() {
33                         TestBroadcaster impl = new TestBroadcaster();
34                         BroadcasterInterface broadcaster = BroadcasterInterface.new_impl(impl);
35                         byte[][] txn = new byte[1][];
36                         txn[0] = new byte[42];
37                         broadcaster.broadcast_transactions(txn);
38                         Assert(impl.broadcasted == true, 3);
39                 }
40
41                 class TestEstimator : FeeEstimatorInterface {
42                         public int get_est_sat_per_1000_weight(ConfirmationTarget confirmation_target) {
43                                 if (confirmation_target == ConfirmationTarget.LDKConfirmationTarget_MinAllowedNonAnchorChannelRemoteFee) {
44                                         return 253;
45                                 } else {
46                                         return 300;
47                                 }
48                         }
49                 }
50
51                 class TestLogger : LoggerInterface {
52                         public void log(Record record) {
53                                 Console.WriteLine(record.get_module_path() + ":" + record.get_line() + " " + record.get_args());
54                         }
55                 }
56
57                 class TestPersister : PersistInterface {
58                         public ChannelMonitorUpdateStatus persist_new_channel(OutPoint channel_id, ChannelMonitor data, MonitorUpdateId update_id) {
59                                 return ChannelMonitorUpdateStatus.LDKChannelMonitorUpdateStatus_Completed;
60                         }
61                         public ChannelMonitorUpdateStatus update_persisted_channel(OutPoint channel_id, ChannelMonitorUpdate update, ChannelMonitor data, MonitorUpdateId update_id) {
62                                 return ChannelMonitorUpdateStatus.LDKChannelMonitorUpdateStatus_Completed;
63                         }
64                 }
65
66                 class TestEventHandler : EventHandlerInterface {
67                         public List<Event> events = new List<Event>();
68                         public void handle_event(Event ev) {
69                                 events.Add(ev);
70                         }
71                 }
72                 static Event get_event(ChannelManager manager) {
73                         TestEventHandler impl = new TestEventHandler();
74                         org.ldk.structs.EventHandler handler = org.ldk.structs.EventHandler.new_impl(impl);
75                         manager.as_EventsProvider().process_pending_events(handler);
76                         Assert(impl.events.Count == 1, 100);
77                         return impl.events[0];
78                 }
79
80                 class Node {
81                         public BroadcasterInterface broadcaster = BroadcasterInterface.new_impl(new TestBroadcaster());
82                         public FeeEstimator estimator = FeeEstimator.new_impl(new TestEstimator());
83                         public Logger logger = Logger.new_impl(new TestLogger());
84                         public Persist persister = Persist.new_impl(new TestPersister());
85                         public ChainParameters chain_params = ChainParameters.of(Network.LDKNetwork_Bitcoin, BestBlock.from_network(Network.LDKNetwork_Bitcoin));
86
87                         public ChainMonitor chain_monitor;
88                         public NetworkGraph graph;
89                         public MultiThreadedLockableScore scorer;
90                         public DefaultRouter router;
91                         public KeysManager keys;
92                         public ChannelManager manager;
93
94                         public Node(byte seed) {
95                                 chain_monitor = ChainMonitor.of(Option_FilterZ.none(), broadcaster, logger, estimator, persister);
96                                 graph = NetworkGraph.of(Network.LDKNetwork_Bitcoin, logger);
97                                 scorer = MultiThreadedLockableScore.of(ProbabilisticScorer.of(ProbabilisticScoringDecayParameters.with_default(), graph, logger).as_Score());
98                                 router = DefaultRouter.of(graph, logger, new byte[32], scorer.as_LockableScore(), ProbabilisticScoringFeeParameters.with_default());
99
100                                 byte[] seed_bytes = new byte[32];
101                                 for (int i = 0; i < 32; i++) seed_bytes[i] = seed;
102                                 keys = KeysManager.of(seed_bytes, 42, 43);
103
104                                 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);
105                         }
106                 }
107
108                 static void NodeTest() {
109                         Node node_a = new Node(1);
110                         Node node_b = new Node(2);
111
112                         InitFeatures init_features = node_a.manager.as_ChannelMessageHandler().provided_init_features(node_b.manager.get_our_node_id());
113                         Init init_msg = Init.of(init_features, Option_CVec_ThirtyTwoBytesZZ.none(), Option_SocketAddressZ.none());
114                         node_a.manager.as_ChannelMessageHandler().peer_connected(node_b.manager.get_our_node_id(), init_msg, false);
115                         node_b.manager.as_ChannelMessageHandler().peer_connected(node_a.manager.get_our_node_id(), init_msg, false);
116
117                         Result_ThirtyTwoBytesAPIErrorZ res = node_a.manager.create_channel(node_b.manager.get_our_node_id(), 100000, 42, new UInt128(43), UserConfig.with_default());
118                         Assert(res.is_ok(), 4);
119
120                         MessageSendEvent[] msgs = node_a.manager.as_MessageSendEventsProvider().get_and_clear_pending_msg_events();
121                         Assert(msgs.Length == 1, 5);
122                         Assert(msgs[0] is MessageSendEvent.MessageSendEvent_SendOpenChannel, 6);
123                         node_b.manager.as_ChannelMessageHandler().handle_open_channel(node_a.manager.get_our_node_id(), ((MessageSendEvent.MessageSendEvent_SendOpenChannel) msgs[0]).msg);
124
125                         MessageSendEvent[] response_msgs = node_b.manager.as_MessageSendEventsProvider().get_and_clear_pending_msg_events();
126                         Assert(response_msgs.Length == 1, 7);
127                         Assert(response_msgs[0] is MessageSendEvent.MessageSendEvent_SendAcceptChannel, 8);
128                         node_a.manager.as_ChannelMessageHandler().handle_accept_channel(node_b.manager.get_our_node_id(), ((MessageSendEvent.MessageSendEvent_SendAcceptChannel) response_msgs[0]).msg);
129
130                         Event funding_ready = get_event(node_a.manager);
131                         Assert(funding_ready is Event.Event_FundingGenerationReady, 9);
132
133                         // We could use funding_transaction_generated here, but test batching
134                         TwoTuple_ThirtyTwoBytesPublicKeyZ[] channel = new TwoTuple_ThirtyTwoBytesPublicKeyZ[1];
135                         channel[0] = TwoTuple_ThirtyTwoBytesPublicKeyZ.of(((Event.Event_FundingGenerationReady) funding_ready).temporary_channel_id, ((Event.Event_FundingGenerationReady) funding_ready).counterparty_node_id);
136
137                         // Hand-crafted transaction which has a dummy witness and can pay to our script
138                         byte[] transaction = new byte[99];
139                         transaction[0] = 2;
140                         transaction[1] = 0;
141                         transaction[2] = 0;
142                         transaction[3] = 0;
143                         transaction[4] = 0;
144                         transaction[5] = 1;
145                         transaction[6] = 1;
146                         transaction[7] = 66;
147                         transaction[8] = 66;
148                         transaction[9] = 66;
149                         transaction[10] = 66;
150                         transaction[11] = 66;
151                         transaction[12] = 66;
152                         transaction[13] = 66;
153                         transaction[14] = 66;
154                         transaction[15] = 66;
155                         transaction[16] = 66;
156                         transaction[17] = 66;
157                         transaction[18] = 66;
158                         transaction[19] = 66;
159                         transaction[20] = 66;
160                         transaction[21] = 66;
161                         transaction[22] = 66;
162                         transaction[23] = 66;
163                         transaction[24] = 66;
164                         transaction[25] = 66;
165                         transaction[26] = 66;
166                         transaction[27] = 66;
167                         transaction[28] = 66;
168                         transaction[29] = 66;
169                         transaction[30] = 66;
170                         transaction[31] = 66;
171                         transaction[32] = 66;
172                         transaction[33] = 66;
173                         transaction[34] = 66;
174                         transaction[35] = 66;
175                         transaction[36] = 66;
176                         transaction[37] = 66;
177                         transaction[38] = 66;
178                         transaction[39] = 18;
179                         transaction[40] = 0;
180                         transaction[41] = 0;
181                         transaction[42] = 0;
182                         transaction[43] = 0;
183                         transaction[44] = 253;
184                         transaction[45] = 255;
185                         transaction[46] = 255;
186                         transaction[47] = 255;
187                         transaction[48] = 1;
188                         transaction[49] = 34;
189                         transaction[50] = 2;
190                         transaction[51] = 0;
191                         transaction[52] = 0;
192                         transaction[53] = 0;
193                         transaction[54] = 0;
194                         transaction[55] = 0;
195                         transaction[56] = 0;
196                         transaction[57] = 34;
197
198                         Assert(((Event.Event_FundingGenerationReady) funding_ready).output_script.Length == 34, 10);
199                         for (int i = 0; i < 34; i++) {
200                                 transaction[58 + i] = ((Event.Event_FundingGenerationReady) funding_ready).output_script[i];
201                         }
202
203                         transaction[92] = 1;
204                         transaction[93] = 1;
205                         transaction[94] = 1;
206                         transaction[95] = 0;
207                         transaction[96] = 0;
208                         transaction[97] = 0;
209                         transaction[98] = 0;
210
211                         node_a.manager.batch_funding_transaction_generated(channel, transaction);
212                 }
213
214                 static void Main(string[] args) {
215                         SimpleConstructionTest();
216                         SimpleTraitTest();
217                         NodeTest();
218
219                         Console.WriteLine("\n\nTESTS PASSED\n\n");
220                         System.GC.Collect();
221                         GC.WaitForPendingFinalizers();
222                 }
223         }
224 }