PascalCoinMiner.pp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534
  1. program PascalCoinMiner;
  2. {$mode objfpc}{$H+}
  3. {$DEFINE UseCThreads}
  4. { Copyright (c) 2017 by Albert Molina
  5. Distributed under the MIT software license, see the accompanying file LICENSE
  6. or visit http://www.opensource.org/licenses/mit-license.php.
  7. This unit is a part of Pascal Coin, a P2P crypto currency without need of
  8. historical operations.
  9. If you like it, consider a donation using BitCoin:
  10. 16K3HCZRhFUtM8GdWRcfKeaa6KsuyxZaYk
  11. }
  12. uses
  13. {$IFDEF UNIX}{$IFDEF UseCThreads}
  14. cthreads,
  15. {$ENDIF}{$ENDIF}
  16. Classes, SysUtils, CustApp, crt, SyncObjs,
  17. UBlockChain, UPoolMinerThreads, UGPUMining,
  18. UPoolMining, ULog, UThread, UAccounts, UCrypto,
  19. UConst, UTime, UJSONFunctions, UNode, UNetProtocol, USha256,
  20. UOpenSSL,
  21. DelphiCL;
  22. type
  23. { TPascalMinerApp }
  24. TPascalMinerApp = class(TCustomApplication)
  25. FLastLogs : TStringList;
  26. procedure ShowGPUDrivers;
  27. procedure OnConnectionStateChanged(Sender : TObject);
  28. procedure OnDeviceStateChanged(Sender : TObject);
  29. procedure OnMinerValuesChanged(Sender : TObject);
  30. procedure OnFoundNOnce(Sender : TCustomMinerDeviceThread; Timestamp, nOnce : Cardinal);
  31. procedure WriteLine(nline : Integer; txt : String);
  32. procedure OnInThreadNewLog(logtype : TLogType; Time : TDateTime; ThreadID : Cardinal; Const sender, logtext : AnsiString);
  33. protected
  34. FWindow32X1,FWindow32Y1,FWindow32X2,FWindow32Y2: DWord;
  35. FLock : TCriticalSection;
  36. FPrivateKey : TECPrivateKey;
  37. FPoolMinerThread : TPoolMinerThread;
  38. FDeviceThreads : TList;
  39. FAppStartTime : TDateTime;
  40. procedure DoRun; override;
  41. public
  42. constructor Create(TheOwner: TComponent); override;
  43. destructor Destroy; override;
  44. procedure WriteHelp; virtual;
  45. end;
  46. Const
  47. CT_MINER_VERSION = '0.4';
  48. CT_Line_DeviceStatus = 3;
  49. CT_Line_ConnectionStatus = 4;
  50. CT_Line_MinerValues = 7;
  51. CT_Line_MiningStatus = 10;
  52. CT_Line_LastFound = 12;
  53. CT_Line_Logs = 15;
  54. CT_MaxLogs = 10;
  55. CT_OpenCL_FileName = 'pascalsha.cl';
  56. { TPascalMinerApp }
  57. procedure TPascalMinerApp.ShowGPUDrivers;
  58. Var i,j,n : Integer;
  59. dev : TDCLDevice;
  60. begin
  61. n := 0;
  62. If Not TGPUDriver.GPUDriver.HasOpenCL then WriteLn('No GPU driver found')
  63. else begin
  64. Writeln('');
  65. WriteLn('** Platforms (Total ',TGPUDriver.GPUDriver.Platforms.PlatformCount,')');
  66. for i:=0 to TGPUDriver.GPUDriver.Platforms.PlatformCount-1 do begin
  67. WriteLn('Platform ',i,' Name:',Trim(TGPUDriver.GPUDriver.Platforms.Platforms[i]^.Name),
  68. ' Version:',Trim(TGPUDriver.GPUDriver.Platforms.Platforms[i]^.Version),
  69. ' Vendor:',Trim(TGPUDriver.GPUDriver.Platforms.Platforms[i]^.Vendor),
  70. ' CPU''s:',TGPUDriver.GPUDriver.Platforms.Platforms[i]^.CPUCount,
  71. ' GPU''s:',TGPUDriver.GPUDriver.Platforms.Platforms[i]^.GPUCount,
  72. ' Devices: ',TGPUDriver.GPUDriver.Platforms.Platforms[i]^.DeviceCount
  73. );
  74. inc(n,TGPUDriver.GPUDriver.Platforms.Platforms[i]^.DeviceCount);
  75. end;
  76. Writeln('');
  77. Writeln('** Platforms and devices available: (Total ',n,')');
  78. for i:=0 to TGPUDriver.GPUDriver.Platforms.PlatformCount-1 do begin
  79. for j:=0 to TGPUDriver.GPUDriver.Platforms.Platforms[i]^.DeviceCount-1 do begin
  80. dev := TGPUDriver.GPUDriver.Platforms.Platforms[i]^.Devices[j]^;
  81. Writeln('-p ',i,' -d ',j,' Name:',Trim(dev.Name),' Compute Units:',dev.MaxComputeUnits,' Max Freq.:',dev.MaxClockFrequency);
  82. end;
  83. end;
  84. end;
  85. end;
  86. procedure TPascalMinerApp.OnConnectionStateChanged(Sender: TObject);
  87. Const CT_state : Array[boolean] of String = ('Disconnected','Connected');
  88. var i : Integer;
  89. s : String;
  90. begin
  91. If FPoolMinerThread.PoolMinerClient.PoolType=ptNone then s:='MINING'
  92. else s:='POOL MINING USER "'+FPoolMinerThread.PoolMinerClient.UserName+'"';
  93. If FPoolMinerThread.PoolMinerClient.Connected then begin
  94. WriteLine(CT_Line_ConnectionStatus,s + ' server: '+FPoolMinerThread.PoolMinerClient.ClientRemoteAddr);
  95. For i:=0 to FDeviceThreads.Count-1 do begin
  96. TCustomMinerDeviceThread(FDeviceThreads[i]).Paused:=false;
  97. end;
  98. end else begin
  99. For i:=0 to FDeviceThreads.Count-1 do begin
  100. TCustomMinerDeviceThread(FDeviceThreads[i]).Paused:=true;
  101. end;
  102. WriteLine(CT_Line_ConnectionStatus,'** NOT CONNECTED '+s + ' Connecting to '+FPoolMinerThread.PoolMinerClient.ClientRemoteAddr);
  103. end;
  104. end;
  105. procedure TPascalMinerApp.OnDeviceStateChanged(Sender: TObject);
  106. Var i : Integer;
  107. s : String;
  108. begin
  109. If Sender is TCustomMinerDeviceThread then begin
  110. If TCustomMinerDeviceThread(Sender).IsMining then WriteLine(CT_Line_DeviceStatus,'') // clear line
  111. else WriteLine(CT_Line_DeviceStatus,'*** Not mining ***');
  112. end;
  113. end;
  114. procedure TPascalMinerApp.OnMinerValuesChanged(Sender: TObject);
  115. begin
  116. If Sender is TCustomMinerDeviceThread then begin
  117. If TCustomMinerDeviceThread(Sender).MinerValuesForWork.block>0 then begin
  118. WriteLine(CT_Line_MinerValues,Format('Current block: %d Wallet Name: "%s" Target: %s',
  119. [TCustomMinerDeviceThread(Sender).MinerValuesForWork.block,
  120. FPoolMinerThread.GlobalMinerValuesForWork.payload_start,
  121. IntToHex(TCustomMinerDeviceThread(Sender).MinerValuesForWork.target,8)
  122. ]));
  123. end;
  124. end;
  125. end;
  126. procedure TPascalMinerApp.OnFoundNOnce(Sender: TCustomMinerDeviceThread; Timestamp, nOnce: Cardinal);
  127. begin
  128. WriteLine(CT_Line_LastFound + FDeviceThreads.Count,FormatDateTime('hh:nn:ss',now)+' Block:'+IntToStr(Sender.MinerValuesForWork.block)+' NOnce:'+Inttostr(nOnce)+
  129. ' Timestamp:'+inttostr(Timestamp)+' Miner:'+Sender.MinerValuesForWork.payload_start);
  130. end;
  131. procedure TPascalMinerApp.WriteLine(nline: Integer; txt: String);
  132. Var i : Integer;
  133. begin
  134. FLock.Acquire;
  135. try
  136. i := length(txt);
  137. if i<=(FWindow32X2-FWindow32X1+1) then begin
  138. setlength(txt,FWindow32X2-FWindow32X1+1);
  139. fillchar(txt[i+1],FWindow32X2-FWindow32X1+1-i,' ');
  140. end else begin
  141. txt := copy(txt,1,FWindow32X2-FWindow32X1+1);
  142. end;
  143. if (nline<=(FWindow32Y2-FWindow32Y1)) then begin
  144. GotoXY32(FWindow32X1,nline);
  145. write(txt);
  146. end;
  147. finally
  148. FLock.Release;
  149. end;
  150. end;
  151. procedure TPascalMinerApp.OnInThreadNewLog(logtype: TLogType; Time: TDateTime;
  152. ThreadID: Cardinal; const sender, logtext: AnsiString);
  153. var msg : String;
  154. i,nline : Integer;
  155. begin
  156. If logtype=ltdebug then exit;
  157. FLock.Acquire;
  158. try
  159. msg := formatdatetime('hh:nn:ss',now)+' '+CT_LogType[logtype]+' '+logtext;
  160. FLastLogs.AddObject(msg,TObject(PtrInt(logtype)));
  161. i := FLastLogs.Count-CT_MaxLogs;
  162. if (i<0) then i:=0;
  163. nline := CT_Line_Logs+FDeviceThreads.Count;
  164. while (i<FLastLogs.Count) do begin
  165. WriteLine(nline,FLastLogs[i]);
  166. inc(nline); inc(i);
  167. end;
  168. if FLastLogs.Count>(CT_MaxLogs*2) then begin
  169. for i:=1 to CT_MaxLogs do FLastLogs.Delete(0);
  170. end;
  171. Finally
  172. FLock.Release;
  173. end;
  174. end;
  175. procedure TPascalMinerApp.DoRun;
  176. var
  177. ErrorMsg: String;
  178. s : String;
  179. nsarr : TNodeServerAddressArray;
  180. Function AddMiners : Boolean;
  181. var p,d,c,i : Integer;
  182. strl : TStringList;
  183. devt : TCustomMinerDeviceThread;
  184. begin
  185. Result := false;
  186. if (Not HasOption('p','platform')) And (Not HasOption('d','device')) And (Not HasOption('c','cpu')) then begin
  187. Writeln('Need to specify -p X and -d Y for GPU mining or -c N for CPU mining. See -h for more info');
  188. ShowGPUDrivers;
  189. Terminate;
  190. Exit;
  191. end;
  192. if HasOption('c','cpu') then begin
  193. c := StrToIntDef(GetOptionValue('c','cpu'),-1);
  194. if (c<=0) or (c>CPUCount) then begin
  195. WriteLn('Invalid cpu value ',c,'. Valid values: 1..',CPUCount);
  196. Terminate;
  197. exit;
  198. end;
  199. devt:= TCPUDeviceThread.Create(FPoolMinerThread,CT_TMinerValuesForWork_NULL);
  200. devt.OnStateChanged:=@OnDeviceStateChanged;
  201. devt.OnMinerValuesChanged:=@OnMinerValuesChanged;
  202. devt.OnFoundNOnce:=@OnFoundNOnce;
  203. TCPUDeviceThread(devt).CPUs:=c;
  204. devt.Paused:=true;
  205. FDeviceThreads.Add(devt);
  206. end else begin
  207. p := StrToIntDef(GetOptionValue('p','platform'),-1);
  208. d := StrToIntDef(GetOptionValue('d','device'),-1);
  209. if (p<0) or (p>=TGPUDriver.GPUDriver.Platforms.PlatformCount) then begin
  210. WriteLn('Invalid Platform ',p,'. Valid values: 0..',TGPUDriver.GPUDriver.Platforms.PlatformCount-1);
  211. Terminate;
  212. exit;
  213. end;
  214. strl := TStringList.Create;
  215. try
  216. if (d<0) then begin
  217. // Is a value separated by commas?
  218. strl.Delimiter:=',';
  219. strl.DelimitedText:=GetOptionValue('d','device');
  220. end else strl.Text:=inttostr(d);
  221. for i:=0 to strl.Count-1 do begin
  222. d := StrToIntDef(strl[i],-1);
  223. if (d<0) or (d>=TGPUDriver.GPUDriver.Platforms.Platforms[p]^.DeviceCount) then begin
  224. WriteLn('Invalid device ',d,'. Valid values: 0..',TGPUDriver.GPUDriver.Platforms.Platforms[p]^.DeviceCount-1);
  225. Terminate;
  226. exit;
  227. end;
  228. //
  229. devt := TGPUDeviceThread.Create(FPoolMinerThread,CT_TMinerValuesForWork_NULL);
  230. devt.OnStateChanged:=@OnDeviceStateChanged;
  231. devt.OnMinerValuesChanged:=@OnMinerValuesChanged;
  232. devt.OnFoundNOnce:=@OnFoundNOnce;
  233. TGPUDeviceThread(devt).Platform:=p;
  234. TGPUDeviceThread(devt).Device:=d;
  235. TGPUDeviceThread(devt).ProgramFileName:=ExtractFileDir(ExeName)+PathDelim+CT_OpenCL_FileName;
  236. devt.Paused:=true;
  237. FDeviceThreads.Add(devt);
  238. end;
  239. finally
  240. strl.Free;
  241. end;
  242. end;
  243. Result := true;
  244. end;
  245. Procedure DoWaitAndLog;
  246. Var tc : Cardinal;
  247. gs,ms : TMinerStats;
  248. hrReal,hrHashing, glhrHashing, glhrReal : Real;
  249. i : Integer;
  250. devt : TCustomMinerDeviceThread;
  251. s : String;
  252. Begin
  253. tc := GetTickCount;
  254. repeat
  255. If FPoolMinerThread.PoolMinerClient.Connected then begin
  256. for i:=0 to FDeviceThreads.Count-1 do begin
  257. TCustomMinerDeviceThread(FDeviceThreads[i]).Paused:=false;
  258. end;
  259. end;
  260. while (Not Terminated) do begin
  261. sleep(100);
  262. //devt := TCustomMinerDeviceThread(FDeviceThreads[0]);
  263. If (tc + 1000)<GetTickCount then begin
  264. tc := GetTickCount;
  265. //ms := devt.DeviceStats;
  266. For i:=0 to FDeviceThreads.Count-1 do begin
  267. devt := TCustomMinerDeviceThread(FDeviceThreads[i]);
  268. ms := devt.DeviceStats;
  269. if ms.WorkingMillisecondsHashing>0 then hrHashing := (((ms.RoundsCount DIV Int64(ms.WorkingMillisecondsHashing)))/(1000))
  270. else hrHashing := 0;
  271. gs := devt.GlobalDeviceStats;
  272. If ms.RoundsCount>0 then begin
  273. s := FormatDateTime('hh:nn:ss',now)+Format(' Miner:"%s" at %0.2f MH/s - Rounds: %0.2f G Found: %d',[devt.MinerValuesForWork.payload_start,hrHashing, gs.RoundsCount/1000000000, gs.WinsCount]);
  274. If (gs.Invalids>0) then s := s +' '+inttostr(gs.Invalids)+' ERRORS!';
  275. WriteLine(CT_Line_MiningStatus+i,s);
  276. end else begin
  277. If gs.RoundsCount>0 then begin
  278. s := FormatDateTime('hh:nn:ss',now)+Format(' Miner:"%s" **NOT MINING** - Rounds: %0.2f G Found: %d',[devt.MinerValuesForWork.payload_start,gs.RoundsCount/1000000000, gs.WinsCount]);
  279. If (gs.Invalids>0) then s := s +' '+inttostr(gs.Invalids)+' ERRORS!';
  280. end else begin
  281. s := FormatDateTime('hh:nn:ss',now)+' Not mining...';
  282. end;
  283. WriteLine(CT_Line_MiningStatus+i,s);
  284. end;
  285. end;
  286. WriteLine(CT_Line_LastFound+FDeviceThreads.Count-1,'MY VALID BLOCKS FOUND: '+IntToStr(gs.WinsCount) +' Working time: '+IntToStr(Trunc(now - FAppStartTime))+'d '+FormatDateTime('hh:nn:ss',Now-FAppStartTime) );
  287. end;
  288. If KeyPressed then begin
  289. If ReadKey in ['c','C','q','Q'] then begin
  290. WriteLine(CT_Line_Logs+FDeviceThreads.Count+CT_MaxLogs,'Finalizing...');
  291. terminate;
  292. end;
  293. end;
  294. end;
  295. until Terminated;
  296. end;
  297. Procedure DoVisualprocess(minerName, UserName, Password : String);
  298. Var sc : tcrtcoord;
  299. Flog : TLog;
  300. devt : TCustomMinerDeviceThread;
  301. i : Integer;
  302. Begin
  303. FPoolMinerThread := TPoolMinerThread.Create(nsarr[0].ip,nsarr[0].port,FPrivateKey.PublicKey);
  304. try
  305. If (UserName<>'') then begin
  306. FPoolMinerThread.PoolMinerClient.PoolType:=ptIdentify;
  307. FPoolMinerThread.PoolMinerClient.UserName:=UserName;
  308. FPoolMinerThread.PoolMinerClient.Password:=Password;
  309. end;
  310. If Not AddMiners then exit;
  311. if HasOption('t','testmode') then begin
  312. i := StrToIntDef(GetOptionValue('t','testmode'),-1);
  313. if (i>=0) And (i<=32) then begin
  314. FPoolMinerThread.TestingPoWLeftBits:=i;
  315. end else begin
  316. WriteLn('Invalid bits for testing mode. value ',i,'. Valid values: 0..32 (0=No testing mode)');
  317. Terminate;
  318. exit;
  319. end;
  320. end;
  321. //
  322. cursoroff;
  323. try
  324. clrscr;
  325. FWindow32X1:=WindMinX;
  326. FWindow32X2:=WindMaxX;
  327. FWindow32Y1:=WindMinY;
  328. FWindow32Y2:=WindMaxY;
  329. WriteLine(1,'** PascalCoin miner ** Version: '+CT_MINER_VERSION);
  330. WriteLine(CT_Line_MinerValues-1,'MINER VALUES:');
  331. WriteLine(CT_Line_MiningStatus-1,'MINING STATUS:');
  332. WriteLine(CT_Line_LastFound+FDeviceThreads.Count-1,'MY VALID BLOCKS FOUND: 0');
  333. WriteLine(CT_Line_Logs+FDeviceThreads.Count-1,'LOGS:');
  334. FPoolMinerThread.MinerAddName:=minerName;
  335. WriteLine(CT_Line_MinerValues-1,'MINER VALUES: (My miner name="'+minerName+'")');
  336. FPoolMinerThread.OnConnectionStateChanged:=@OnConnectionStateChanged;
  337. OnConnectionStateChanged(FPoolMinerThread);
  338. If (FDeviceThreads.Count)=1 then begin
  339. devt := TCustomMinerDeviceThread(FDeviceThreads[0]);
  340. WriteLine(2,devt.MinerDeviceName);
  341. end else begin
  342. WriteLine(2,'Mining using '+IntToStr(FDeviceThreads.Count)+' devices');
  343. end;
  344. Flog := TLog.Create(Nil);
  345. try
  346. Flog.OnInThreadNewLog:=@OnInThreadNewLog;
  347. DoWaitAndLog;
  348. finally
  349. FLog.free;
  350. end;
  351. finally
  352. cursoron;
  353. end;
  354. Finally
  355. FPoolMinerThread.Terminate;
  356. FPoolMinerThread.Free;
  357. end;
  358. end;
  359. Var username,password : String;
  360. begin
  361. FLastLogs := TStringList.Create;
  362. FLock := TCriticalSection.Create;
  363. Try
  364. // quick check parameters
  365. ErrorMsg:=CheckOptions('hp:d:s::c:n::t:u::x::', 'help platform device server cpu minername testmode user pwd');
  366. if ErrorMsg<>'' then begin
  367. //ShowException(Exception.Create(ErrorMsg));
  368. WriteLn(ErrorMsg);
  369. Exit;
  370. end;
  371. // parse parameters
  372. if HasOption('h', 'help') then begin
  373. WriteHelp;
  374. Exit;
  375. end;
  376. if (Not HasOption('p','platform')) And (Not HasOption('d','device')) And (Not HasOption('c','cpu:')) then begin
  377. Writeln('Need to specify -p X and -d Y for GPU mining or -c N for CPU mining');
  378. Writeln('Execute ',ExtractFileName(ExeName),' -h for more info');
  379. ShowGPUDrivers;
  380. Exit;
  381. end;
  382. If Not FileExists(ExtractFileDir(ExeName)+PathDelim+CT_OpenCL_FileName) then begin
  383. Writeln('**********************');
  384. Writeln('OpenCL file not found!');
  385. Writeln('File: ',CT_OpenCL_FileName);
  386. Exit;
  387. end;
  388. If HasOption('s','server') then begin
  389. s := Trim(GetOptionValue('s','server'));
  390. if (s='') then s := 'localhost:'+inttostr(CT_JSONRPCMinerServer_Port);
  391. end else s:='';
  392. if (s='') then begin
  393. WriteLn('Input server name (default is localhost:',CT_JSONRPCMinerServer_Port,'):');
  394. Readln(s);
  395. trim(s);
  396. if (s='') then s := 'localhost:'+inttostr(CT_JSONRPCMinerServer_Port);
  397. end;
  398. if (pos(':',s)=0) then begin
  399. s := trim(s) + ':'+inttostr(CT_JSONRPCMinerServer_Port);
  400. end;
  401. TNode.DecodeIpStringToNodeServerAddressArray(s,nsarr);
  402. if (length(nsarr)<>1) then begin
  403. Writeln('INVALID SERVER VALUE ',s);
  404. WriteHelp;
  405. Exit;
  406. end;
  407. If (Not HasOption('n','minername')) then begin
  408. WriteLn('Input miner name that will be added to server miner name:');
  409. Readln(s);
  410. end else s:=GetOptionValue('n','minername');
  411. Try
  412. TCrypto.InitCrypto;
  413. Except
  414. On E:Exception do begin
  415. Writeln('**************************');
  416. Writeln('Error initializing library '+SSL_C_LIB+' (Not found or not valid)');
  417. Writeln('Error message: '+E.Message);
  418. Writeln('**************************');
  419. Exit;
  420. end;
  421. end;
  422. username:='';
  423. password:='';
  424. If (HasOption('u','user')) Or (HasOption('x','pwd')) then begin
  425. username:=trim(GetOptionValue('u','user'));
  426. password:=trim(GetOptionValue('x','pwd'));
  427. if (username='') then begin
  428. WriteLn('Input Pool username (or empty for non pool connection):');
  429. Readln(username);
  430. end;
  431. if (password='') And (username<>'') then begin
  432. WriteLn('Input Pool password for user ',username,':');
  433. Readln(password);
  434. end;
  435. end;
  436. FPrivateKey := TECPrivateKey.Create;
  437. Try
  438. FPrivateKey.GenerateRandomPrivateKey(CT_Default_EC_OpenSSL_NID);
  439. DoVisualprocess(s,username,password);
  440. finally
  441. FreeAndNil(FPrivateKey);
  442. end;
  443. finally
  444. FreeAndNil(FLock);
  445. FreeAndNil(FLastLogs);
  446. if not terminated then
  447. Terminate;
  448. end;
  449. end;
  450. constructor TPascalMinerApp.Create(TheOwner: TComponent);
  451. Var FLog : TLog;
  452. begin
  453. inherited Create(TheOwner);
  454. FDeviceThreads := TList.Create;
  455. StopOnException:=True;
  456. FAppStartTime := Now;
  457. FLog := TLog.Create(self);
  458. FLog.SaveTypes:=CT_TLogTypes_DEFAULT;
  459. FLog.FileName:=ExtractFileDir(ExeName)+PathDelim+'PascalCoinMiner.log';
  460. end;
  461. destructor TPascalMinerApp.Destroy;
  462. begin
  463. FreeAndNil(FDeviceThreads);
  464. inherited Destroy;
  465. end;
  466. procedure TPascalMinerApp.WriteHelp;
  467. begin
  468. { add your help code here }
  469. writeln('PascalCoin Miner - Version: ',CT_MINER_VERSION);
  470. writeln('Usage: ', ExtractFileName(ExeName), ' -h -s S -p X -d Y -c N -n MYNAME');
  471. writeln(' -h for help');
  472. writeln(' -s S (S is PascalCoin server:port where default value is localhost:',CT_JSONRPCMinerServer_Port,')');
  473. writeln(' -p X (X is GPU platform)');
  474. writeln(' -d Y (Y is GPU device for platform)');
  475. writeln(' Y can be multiple devices. Example -d 0,2,3 Will use devices 0, 2 and 3');
  476. writeln(' -c N (For CPU mining, where N is CPU''s to use. Activating this disable GPU mining)');
  477. writeln(' -n MYNAME (Will add MYNAME value to miner name assigned by server)');
  478. writeln(' ** POOL IDENTIFICATION PROTOCOL **');
  479. writeln(' (Not needed for PascalCoin core, only some third party pools)');
  480. writeln(' -u USERNAME');
  481. writeln(' -x PASSWORD');
  482. writeln('');
  483. writeln('Basic example GPU mining over multiple devices: ');
  484. writeln(' ',ExtractFileName(ExeName),' -p 0 -d 0,1,2,3 -s -n ABC');
  485. writeln(' (Devices 0,1,2,3 at server localhost:',CT_JSONRPCMinerServer_Port,' miner name ABC)');
  486. writeln('');
  487. ShowGPUDrivers;
  488. end;
  489. var
  490. Application: TPascalMinerApp;
  491. begin
  492. Application:=TPascalMinerApp.Create(nil);
  493. Application.Title:='Pascal Miner';
  494. Application.Run;
  495. Application.Free;
  496. end.