1+ using System . Collections . Immutable ;
2+ using System . Diagnostics ;
3+ using System . Security . Cryptography ;
4+ using Dasync . Collections ;
5+ using Docker . DotNet ;
6+ using dotnet_etcd ;
7+ using Google . Protobuf ;
8+ using Google . Protobuf . Collections ;
9+ using Grpc . Core ;
10+ using Invoicesrpc ;
11+ // using LNBolt;
12+ using Lnrpc ;
13+ using LNUnit . Extentions ;
14+ using LNUnit . LND ;
15+ using LNUnit . Setup ;
16+ using LNUnit . Tests . Fixture ;
17+ using Microsoft . Extensions . Caching . Memory ;
18+ using Microsoft . Extensions . Configuration ;
19+ using Microsoft . Extensions . DependencyInjection ;
20+ using NBitcoin ;
21+ using Routerrpc ;
22+ using Serilog ;
23+ using ServiceStack ;
24+ using ServiceStack . Text ;
25+ using Walletrpc ;
26+ using AddressType = Lnrpc . AddressType ;
27+ using Assert = NUnit . Framework . Assert ;
28+ using ListUnspentRequest = Lnrpc . ListUnspentRequest ;
29+ using Network = NBitcoin . Network ;
30+ using Transaction = Walletrpc . Transaction ;
31+
32+ namespace LNUnit . Tests . Abstract ;
33+
34+
35+ public abstract class EctdLightningAbstractTests : IDisposable
36+ {
37+ public EctdLightningAbstractTests ( string dbType ,
38+ string lndImage = "custom_lnd" ,
39+ string tag = "latest" ,
40+ string lndRoot = "/root/.lnd" ,
41+ bool pullImage = false
42+ )
43+ {
44+ _dbType = dbType ;
45+ _lndImage = lndImage ;
46+ _tag = tag ;
47+ _lndRoot = lndRoot ;
48+ _pullImage = pullImage ;
49+ }
50+
51+ [ SetUp ]
52+ public async Task PerTestSetUp ( )
53+ {
54+ Builder . CancelAllInterceptors ( ) ;
55+ Builder . NewBlock ( ) ; //tick toc new block
56+ await Builder . NewBlock ( ) ;
57+ }
58+
59+ [ OneTimeSetUp ]
60+ public async Task OneTimeSetup ( )
61+ {
62+ var configuration = new ConfigurationBuilder ( )
63+ . SetBasePath ( Directory . GetCurrentDirectory ( ) ) // Set the current directory as the base path
64+ . AddJsonFile ( "appsettings.json" , false , true )
65+ . AddJsonFile ( "appsettings.Development.json" , false , true )
66+ . Build ( ) ;
67+ var services = new ServiceCollection ( ) ;
68+ var loggerConfiguration = new LoggerConfiguration ( ) . Enrich . FromLogContext ( ) ;
69+ loggerConfiguration . ReadFrom . Configuration ( configuration ) ;
70+ Log . Logger = loggerConfiguration . CreateLogger ( ) ;
71+ services . AddLogging ( ) ;
72+ services . AddSerilog ( Log . Logger , true ) ;
73+ _serviceProvider = services . BuildServiceProvider ( ) ;
74+ Builder = ActivatorUtilities . CreateInstance < LNUnitBuilder > ( _serviceProvider ) ;
75+
76+ if ( _dbType == "postgres" )
77+ {
78+ PostgresFixture . AddDb ( "alice" ) ;
79+ PostgresFixture . AddDb ( "bob" ) ;
80+ PostgresFixture . AddDb ( "carol" ) ;
81+ }
82+
83+ await _client . CreateDockerImageFromPath ( "../../../../Docker/lnd" , [ "custom_lnd" , "custom_lnd:latest" ] ) ;
84+ await _client . CreateDockerImageFromPath ( "./../../../../Docker/bitcoin/30.0" , [ "bitcoin:latest" , "bitcoin:30.0" ] ) ;
85+ await SetupNetwork ( _lndImage , _tag , _lndRoot , _pullImage , bitcoinImage : "bitcoin" , bitcoinTag : "30.0" , pullBitcoinImage : false ) ;
86+ }
87+
88+
89+
90+ public string DbContainerName { get ; set ; } = "postgres" ;
91+ private readonly DockerClient _client = new DockerClientConfiguration ( ) . CreateClient ( ) ;
92+
93+ private ServiceProvider _serviceProvider ;
94+
95+ public void Dispose ( )
96+ {
97+ GC . SuppressFinalize ( this ) ;
98+
99+ // Remove containers
100+ _client . RemoveContainer ( "miner" ) . GetAwaiter ( ) . GetResult ( ) ;
101+ _client . RemoveContainer ( "alice" ) . GetAwaiter ( ) . GetResult ( ) ;
102+ _client . RemoveContainer ( "bob" ) . GetAwaiter ( ) . GetResult ( ) ;
103+ _client . RemoveContainer ( "carol" ) . GetAwaiter ( ) . GetResult ( ) ;
104+
105+ Builder ? . Destroy ( ) ;
106+ Builder ? . Dispose ( ) ;
107+ _client . Dispose ( ) ;
108+ }
109+
110+ public LNUnitBuilder ? Builder { get ; private set ; }
111+
112+
113+ public async Task SetupNetwork ( string lndImage = "lightninglabs/lnd" , string lndTag = "daily-testing-only" ,
114+ string lndRoot = "/root/.lnd" , bool pullLndImage = false , string bitcoinImage = "polarlightning/bitcoind" , string bitcoinTag = "29.0" ,
115+ bool pullBitcoinImage = false )
116+ {
117+ await _client . RemoveContainer ( "miner" ) ;
118+ await _client . RemoveContainer ( "alice" ) ;
119+ await _client . RemoveContainer ( "bob" ) ;
120+ await _client . RemoveContainer ( "carol" ) ;
121+ await _client . RemoveContainer ( "etcd" ) ;
122+
123+ Builder . AddBitcoinCoreNode ( image : bitcoinImage , tag : bitcoinTag , pullImage : pullBitcoinImage ) ;
124+
125+ if ( pullLndImage )
126+ {
127+ await _client . PullImageAndWaitForCompleted ( lndImage , lndTag ) ;
128+ }
129+
130+ if ( pullBitcoinImage )
131+ {
132+ await _client . PullImageAndWaitForCompleted ( bitcoinImage , bitcoinTag ) ;
133+ }
134+
135+
136+ Builder . AddPolarLNDNode ( "alice" ,
137+ [
138+ new LNUnitNetworkDefinition . Channel
139+ {
140+ ChannelSize = 10_000_000 , //10MSat
141+ RemoteName = "bob"
142+ } ,
143+ new LNUnitNetworkDefinition . Channel
144+ {
145+ ChannelSize = 10_000_000 , //10MSat
146+ RemoteName = "bob"
147+ } ,
148+ new LNUnitNetworkDefinition . Channel
149+ {
150+ ChannelSize = 10_000_000 , //10MSat
151+ RemoteName = "bob"
152+ } ,
153+ new LNUnitNetworkDefinition . Channel
154+ {
155+ ChannelSize = 10_000_000 , //10MSat
156+ RemoteName = "bob"
157+ }
158+ ] , imageName : lndImage , tagName : lndTag , pullImage : false , acceptKeysend : true , mapTotmp : false ,
159+ postgresDSN : _dbType == "postgres" ? PostgresFixture . LNDConnectionStrings [ "alice" ] : null , lndkSupport : false , nativeSql : _dbType != "boltdb" , storeFinalHtlcResolutions : true ) ;
160+
161+ Builder . AddPolarLNDNode ( "bob" ,
162+ [
163+ new LNUnitNetworkDefinition . Channel
164+ {
165+ ChannelSize = 10_000_000 , //10MSat
166+ RemotePushOnStart = 1_000_000 , // 1MSat
167+ RemoteName = "alice"
168+ }
169+ ] , imageName : lndImage , tagName : lndTag , pullImage : false , acceptKeysend : true , mapTotmp : false ,
170+ postgresDSN : _dbType == "postgres" ? PostgresFixture . LNDConnectionStrings [ "bob" ] : null , lndkSupport : false , nativeSql : _dbType != "boltdb" ) ;
171+
172+ Builder . AddPolarLNDNode ( "carol" ,
173+ [
174+ new LNUnitNetworkDefinition . Channel
175+ {
176+ ChannelSize = 10_000_000 , //10MSat
177+ RemotePushOnStart = 1_000_000 , // 1MSat
178+ RemoteName = "bob"
179+ } ,
180+ new LNUnitNetworkDefinition . Channel
181+ {
182+ ChannelSize = 10_000_000 , //10MSat
183+ RemotePushOnStart = 1_000_000 , // 1MSat
184+ RemoteName = "bob"
185+ } ,
186+ new LNUnitNetworkDefinition . Channel
187+ {
188+ ChannelSize = 10_000_000 , //10MSat
189+ RemotePushOnStart = 1_000_000 , // 1MSat
190+ RemoteName = "bob"
191+ } ,
192+ new LNUnitNetworkDefinition . Channel
193+ {
194+ ChannelSize = 10_000_000 , //10MSat
195+ RemotePushOnStart = 1_000_000 , // 1MSat
196+ RemoteName = "bob"
197+ }
198+ ] , imageName : lndImage , tagName : lndTag , pullImage : false , acceptKeysend : true , mapTotmp : false ,
199+ postgresDSN : _dbType == "postgres" ? PostgresFixture . LNDConnectionStrings [ "carol" ] : null , lndkSupport : false , nativeSql : _dbType != "boltdb" ) ;
200+
201+ await Builder . Build ( lndRoot : lndRoot , ectdEnabled : true ) ;
202+
203+ await WaitNodesReady ( ) ;
204+ await WaitGraphReady ( ) ;
205+ }
206+
207+ private async Task WaitNodesReady ( )
208+ {
209+ var a = await Builder . WaitUntilAliasIsServerReady ( "alice" ) ;
210+ var b = await Builder . WaitUntilAliasIsServerReady ( "bob" ) ;
211+ var c = await Builder . WaitUntilAliasIsServerReady ( "carol" ) ;
212+ //Task.WaitAll(a, b, c);
213+ }
214+
215+ private async Task WaitGraphReady ( string fromAlias = "alice" )
216+ {
217+ var graphReady = false ;
218+ while ( ! graphReady )
219+ {
220+ var graph = await Builder . GetGraphFromAlias ( fromAlias ) ;
221+ if ( graph . Nodes . Count < 3 )
222+ {
223+ "Graph not ready..." . Print ( ) ;
224+ await Task . Delay ( 250 ) ; //let the graph sync
225+ }
226+ else
227+ {
228+ graphReady = true ;
229+ }
230+ }
231+ }
232+
233+
234+ public async Task < bool > IsRunning ( )
235+ {
236+ try
237+ {
238+ var inspect = await _client . Containers . InspectContainerAsync ( DbContainerName ) ;
239+ return inspect . State . Running ;
240+ }
241+ catch
242+ {
243+ // ignored
244+ }
245+
246+ return false ;
247+ }
248+
249+ [ Test ]
250+ public async Task CheckEctdRunning ( )
251+ {
252+ var inspect = await _client . Containers . InspectContainerAsync ( "etcd" ) ;
253+ Assert . IsTrue ( inspect . State . Running , "Etcd running is not running" ) ;
254+ var x = new EtcdClient ( "http://localhost:2379" ) ;
255+
256+
257+ }
258+
259+ [ Test ]
260+ [ Timeout ( 2000 ) ]
261+ [ Category ( "Version" ) ]
262+ [ NonParallelizable ]
263+ public async Task CheckLNDVersion ( )
264+ {
265+ var n = await Builder . WaitUntilAliasIsServerReady ( "alice" ) ;
266+ var info = n . LightningClient . GetInfo ( new GetInfoRequest ( ) ) ;
267+ info . Version . Print ( ) ;
268+ }
269+
270+
271+ private readonly MemoryCache _aliasCache = new ( new MemoryCacheOptions { SizeLimit = 10000 } ) ;
272+ protected readonly string _dbType ;
273+ protected readonly string _lndImage ;
274+ protected readonly string _tag ;
275+ protected readonly string _lndRoot ;
276+ protected readonly bool _pullImage ;
277+
278+ private async Task < string > ToAlias ( LNDNodeConnection c , string remotePubkey )
279+ {
280+ _aliasCache . TryGetValue ( remotePubkey , out string alias ) ;
281+ if ( alias . IsNullOrEmpty ( ) )
282+ try
283+ {
284+ var nodeInfo = await c . LightningClient . GetNodeInfoAsync ( new NodeInfoRequest { PubKey = remotePubkey } ) ;
285+ _aliasCache . Set ( remotePubkey , nodeInfo . Node . Alias ,
286+ new MemoryCacheEntryOptions
287+ {
288+ AbsoluteExpirationRelativeToNow = TimeSpan . FromHours ( 1 ) ,
289+ Size = 1
290+ } ) ;
291+ return nodeInfo . Node . Alias ;
292+ }
293+ catch ( Exception e )
294+ {
295+ return remotePubkey ;
296+ }
297+
298+ return alias ;
299+ }
300+
301+
302+ }
0 commit comments