Browse Source

Merge pull request #1 from PascalCoinDev/master

Update from Master
UrbanCohortDev 4 years ago
parent
commit
b805c34db7

+ 4 - 1
CHANGELOG.md

@@ -1,10 +1,13 @@
 # Changelog
 # Changelog
 
 
 ## Build 5.4 - (PENDING RELEASE)
 ## Build 5.4 - (PENDING RELEASE)
+- Added "DATAFOLDER" configuration option at pascalcoin_daemon.ini file (daemon/service) in order to allow customize data folder
 - Added usage of AbstractMem library to allow build a PascalCoin version using virtual memory and efficient caching mechanism
 - Added usage of AbstractMem library to allow build a PascalCoin version using virtual memory and efficient caching mechanism
   - Must activate {$DEFINE USE_ABSTRACTMEM} at config.inc file
   - Must activate {$DEFINE USE_ABSTRACTMEM} at config.inc file
 - Improved performance when downloading Safebox (Fresh installation)
 - Improved performance when downloading Safebox (Fresh installation)
-- Fixed minor bugs
+- Fixed bugs:
+  - Fixed bugs on "pascalcoin_daemon" (daemon on Linux / Service on Windows) that produced crash on windows and some invalid finalization on Linux
+  - Fixed minor bugs
 
 
 ## Build 5.3.0 - 2020-03-12
 ## Build 5.3.0 - 2020-03-12
 - Fixed "out of memory" error when downloading Safebox
 - Fixed "out of memory" error when downloading Safebox

+ 3 - 1
README.md

@@ -57,4 +57,6 @@ View the changelog [here](CHANGELOG.md)
 
 
 ## Donations  
 ## Donations  
   
   
-Consider a donation using BitCoin to `16K3HCZRhFUtM8GdWRcfKeaa6KsuyxZaYk`
+Consider a donation using Pascal coin to development account: `0-10`
+
+Also, consider a donation using BitCoin to `16K3HCZRhFUtM8GdWRcfKeaa6KsuyxZaYk`

+ 8 - 0
src/config.inc

@@ -66,7 +66,13 @@
   
   
   // Activate ABSTRACTMEM library. Will use a virtual memory caching mechanism for efficient usage without high RAM requirements
   // Activate ABSTRACTMEM library. Will use a virtual memory caching mechanism for efficient usage without high RAM requirements
   {$DEFINE USE_ABSTRACTMEM}
   {$DEFINE USE_ABSTRACTMEM}
+
+  // Activate GNUGETTEXT library
+  {$DEFINE USE_GNUGETTEXT}
   
   
+  // Activate usage of TPCTemporalFileStream instead of TBytes in order to minimize mem usage
+  // This also fixes issue #207 High memory usage on FreePascal compiler
+  {$DEFINE USE_BIGBLOCKS_MEM_ON_DISK}
 
 
 { ********************************************************************
 { ********************************************************************
   Don't touch more code, it will addapt based on your preferences
   Don't touch more code, it will addapt based on your preferences
@@ -117,6 +123,8 @@ ERROR: You must select ONLY ONE option: Use_OpenSSL or Use_CryptoLib4Pascal
   {$IF COMPILERVERSION > 33}
   {$IF COMPILERVERSION > 33}
     {$DEFINE DELPHI_SYDNEY_PLUS}  
     {$DEFINE DELPHI_SYDNEY_PLUS}  
   {$ENDIF}
   {$ENDIF}
+{$ELSE}
+  {$UNDEF USE_GNUGETTEXT}
 {$ENDIF}
 {$ENDIF}
 
 
 
 

+ 25 - 2
src/core/UAccounts.pas

@@ -480,7 +480,19 @@ Procedure Check_Safebox_Integrity(sb : TPCSafebox; title: String);
 implementation
 implementation
 
 
 uses
 uses
-  ULog, {$IFnDEF USE_ABSTRACTMEM} UAccountKeyStorage,{$ENDIF} math, UCommon, UPCOperationsBlockValidator;
+  ULog, {$IFnDEF USE_ABSTRACTMEM} UAccountKeyStorage,{$ENDIF} math, UCommon, UPCOperationsBlockValidator, UPCTemporalFileStream;
+
+
+{$IFDEF FPC}
+  {$DEFINE USE_BIGBLOCKS_MEM_ON_DISK}
+  // USE_BIGBLOCKS_MEM_ON_DISK directive is used in order to prevent a FreePascal issue with Heap allocation strategy that
+  // reuses big blocks of disposed memory and fragments it, this causes that when a new big block of same size that previously
+  // freeded mem is needed it will not reuse because has been fragmented...
+  // Tested on FPC version 3.2.0 (2020-11-03) and order versions
+  // Defragmention documented here: https://www.freepascal.org/docs-html/current/prog/progsu172.html
+  // This issue is not detected on current Delphi memory manager (Tested on Delphi 10.3.2)
+{$ENDIF}
+
 
 
 { This function is for testing purpose only.
 { This function is for testing purpose only.
   Will check if Account Names are well assigned and stored }
   Will check if Account Names are well assigned and stored }
@@ -2181,7 +2193,7 @@ Type
     newBlocks : TOrderedBlockAccountList; // Saves final blocks values on modified blocks
     newBlocks : TOrderedBlockAccountList; // Saves final blocks values on modified blocks
     namesDeleted : TOrderedRawList;
     namesDeleted : TOrderedRawList;
     namesAdded : TOrderedRawList;
     namesAdded : TOrderedRawList;
-    oldBufferBlocksHash: TBytesBuffer;
+    oldBufferBlocksHash: {$IFDEF USE_BIGBLOCKS_MEM_ON_DISK}TPCTemporalFileStream{$ELSE}TBytesBuffer{$ENDIF};
     oldTotalBalance: Int64;
     oldTotalBalance: Int64;
     oldTotalFee: Int64;
     oldTotalFee: Int64;
     oldSafeBoxHash : TRawBytes;
     oldSafeBoxHash : TRawBytes;
@@ -2347,7 +2359,12 @@ begin
     Psnapshot^.newBlocks := FModifiedBlocksFinalState;
     Psnapshot^.newBlocks := FModifiedBlocksFinalState;
     Psnapshot^.namesDeleted := FDeletedNamesSincePreviousSafebox;
     Psnapshot^.namesDeleted := FDeletedNamesSincePreviousSafebox;
     Psnapshot^.namesAdded := FAddedNamesSincePreviousSafebox;
     Psnapshot^.namesAdded := FAddedNamesSincePreviousSafebox;
+    {$IFDEF USE_BIGBLOCKS_MEM_ON_DISK}
+    Psnapshot^.oldBufferBlocksHash := TPCTemporalFileStream.Create('oldbufferblockhash');
+    BufferBlocksHash.SaveToStream( Psnapshot^.oldBufferBlocksHash );
+    {$ELSE}
     Psnapshot^.oldBufferBlocksHash := TBytesBuffer.CreateCopy(BufferBlocksHash);
     Psnapshot^.oldBufferBlocksHash := TBytesBuffer.CreateCopy(BufferBlocksHash);
+    {$ENDIF}
     Psnapshot^.oldTotalBalance:=FTotalBalance;
     Psnapshot^.oldTotalBalance:=FTotalBalance;
     Psnapshot^.oldTotalFee:=FTotalFee;
     Psnapshot^.oldTotalFee:=FTotalFee;
     Psnapshot^.oldSafeBoxHash := FSafeBoxHash;
     Psnapshot^.oldSafeBoxHash := FSafeBoxHash;
@@ -2923,7 +2940,13 @@ begin
         //
         //
         FPreviousSafeBox.FSubChains.Add(Self);
         FPreviousSafeBox.FSubChains.Add(Self);
         //
         //
+        {$IFDEF USE_BIGBLOCKS_MEM_ON_DISK}
+        BufferBlocksHash.Clear;
+        BufferBlocksHash.LoadFromStream( Psnapshot^.oldBufferBlocksHash );
+        {$ELSE}
         BufferBlocksHash.CopyFrom( Psnapshot^.oldBufferBlocksHash );
         BufferBlocksHash.CopyFrom( Psnapshot^.oldBufferBlocksHash );
+        {$ENDIF}
+
         FTotalBalance := Psnapshot^.oldTotalBalance;
         FTotalBalance := Psnapshot^.oldTotalBalance;
         FTotalFee := Psnapshot^.oldTotalFee;
         FTotalFee := Psnapshot^.oldTotalFee;
         FSafeBoxHash := Psnapshot^.oldSafeBoxHash;
         FSafeBoxHash := Psnapshot^.oldSafeBoxHash;

+ 29 - 1
src/core/UBaseTypes.pas

@@ -98,13 +98,16 @@ Type
     function Replace(startPos : Integer; const buffer : TBytes) : Integer; overload;
     function Replace(startPos : Integer; const buffer : TBytes) : Integer; overload;
     function Replace(startPos : Integer; const buffer; bufferSize : Integer) : Integer; overload;
     function Replace(startPos : Integer; const buffer; bufferSize : Integer) : Integer; overload;
     property DefaultIncrement : Integer read FDefaultIncrement write SetDefaultIncrement;
     property DefaultIncrement : Integer read FDefaultIncrement write SetDefaultIncrement;
-    function Compare(ABytesBuffer : TBytesBuffer) : Integer;
+    function Compare(ABytesBuffer : TBytesBuffer) : Integer; overload;
+    function Compare(AStream : TStream) : Integer; overload;
     procedure SetLength(ANewLength : Integer);
     procedure SetLength(ANewLength : Integer);
     function Memory : Pointer;
     function Memory : Pointer;
     function MemoryLength : Integer;
     function MemoryLength : Integer;
     procedure Clear;
     procedure Clear;
     procedure CopyFrom(ABytesBuffer : TBytesBuffer);
     procedure CopyFrom(ABytesBuffer : TBytesBuffer);
     function Capture(AStartPos, ALength : Integer) : TBytes;
     function Capture(AStartPos, ALength : Integer) : TBytes;
+    procedure SaveToStream(AStream : TStream);
+    procedure LoadFromStream(AStream : TStream);
   end;
   end;
 
 
 
 
@@ -624,6 +627,11 @@ begin
   end;
   end;
 end;
 end;
 
 
+procedure TBytesBuffer.SaveToStream(AStream: TStream);
+begin
+  AStream.Write(FBytes[0],Self.Length);
+end;
+
 procedure TBytesBuffer.SetDefaultIncrement(AValue: Integer);
 procedure TBytesBuffer.SetDefaultIncrement(AValue: Integer);
 begin
 begin
   if AValue<=0 then FDefaultIncrement:=1024
   if AValue<=0 then FDefaultIncrement:=1024
@@ -690,6 +698,18 @@ begin
   end;
   end;
 end;
 end;
 
 
+function TBytesBuffer.Compare(AStream: TStream): Integer;
+var Lbb : TBytesBuffer;
+begin
+  Lbb := TBytesBuffer.Create(DefaultIncrement);
+  try
+    Lbb.LoadFromStream(AStream);
+    Result := Compare(Lbb);
+  finally
+    Lbb.Free;
+  end;
+end;
+
 procedure TBytesBuffer.CopyFrom(ABytesBuffer: TBytesBuffer);
 procedure TBytesBuffer.CopyFrom(ABytesBuffer: TBytesBuffer);
 begin
 begin
   System.SetLength(FBytes,System.Length(ABytesBuffer.FBytes));
   System.SetLength(FBytes,System.Length(ABytesBuffer.FBytes));
@@ -725,6 +745,14 @@ begin
   Result := FUsedBytes;
   Result := FUsedBytes;
 end;
 end;
 
 
+procedure TBytesBuffer.LoadFromStream(AStream: TStream);
+begin
+  AStream.Position := 0;
+  IncreaseSize(Self.Length + AStream.Size);
+  AStream.Read(FBytes[FUsedBytes],AStream.Size);
+  SetLength(Self.Length + AStream.Size);
+end;
+
 function TBytesBuffer.Memory: Pointer;
 function TBytesBuffer.Memory: Pointer;
 begin
 begin
   Result := addr(FBytes[0]);
   Result := addr(FBytes[0]);

+ 9 - 9
src/core/UConst.pas

@@ -41,9 +41,9 @@ Const
     {$IFDEF PRODUCTION}'00000003A29C32E84A539ADE24397D41D30116A6FAFEC17B7D9CED68A4238C92'{$ELSE}{$IFDEF TESTNET}''{$ELSE}{$ENDIF}{$ENDIF};
     {$IFDEF PRODUCTION}'00000003A29C32E84A539ADE24397D41D30116A6FAFEC17B7D9CED68A4238C92'{$ELSE}{$IFDEF TESTNET}''{$ELSE}{$ENDIF}{$ENDIF};
 
 
 
 
-  CT_NetServer_Port = {$IFDEF PRODUCTION}4004{$ELSE}{$IFDEF TESTNET}4604{$ELSE}{$ENDIF}{$ENDIF};
-  CT_JSONRPCMinerServer_Port = {$IFDEF PRODUCTION}4009{$ELSE}{$IFDEF TESTNET}4609{$ELSE}{$ENDIF}{$ENDIF};
-  CT_JSONRPC_Port = {$IFDEF PRODUCTION}4003{$ELSE}{$IFDEF TESTNET}4603{$ELSE}{$ENDIF}{$ENDIF};
+  CT_NetServer_Port = {$IFDEF PRODUCTION}4004{$ELSE}{$IFDEF TESTNET}4204{$ELSE}{$ENDIF}{$ENDIF};
+  CT_JSONRPCMinerServer_Port = {$IFDEF PRODUCTION}4009{$ELSE}{$IFDEF TESTNET}4209{$ELSE}{$ENDIF}{$ENDIF};
+  CT_JSONRPC_Port = {$IFDEF PRODUCTION}4003{$ELSE}{$IFDEF TESTNET}4203{$ELSE}{$ENDIF}{$ENDIF};
   CT_AccountsPerBlock = 5;
   CT_AccountsPerBlock = 5;
 
 
   CT_NewLineSecondsAvg: Cardinal = {$IFDEF PRODUCTION}300{$ELSE}{$IFDEF TESTNET}30{$ELSE}{$ENDIF}{$ENDIF};
   CT_NewLineSecondsAvg: Cardinal = {$IFDEF PRODUCTION}300{$ELSE}{$IFDEF TESTNET}30{$ELSE}{$ENDIF}{$ENDIF};
@@ -76,7 +76,7 @@ Const
     {$IFDEF PRODUCTION}$16000000{$ELSE}$08000000{$ENDIF};
     {$IFDEF PRODUCTION}$16000000{$ELSE}$08000000{$ENDIF};
   {$ENDIF}
   {$ENDIF}
   CT_MinCompactTarget_v5: Cardinal = // Minimum compact target of block if using Protocol 5 or higher
   CT_MinCompactTarget_v5: Cardinal = // Minimum compact target of block if using Protocol 5 or higher
-    {$IFDEF PRODUCTION}$12000000{$ELSE}{$IFDEF TESTNET}$0D000000{$ELSE}{$ENDIF}{$ENDIF};
+    {$IFDEF PRODUCTION}$12000000{$ELSE}{$IFDEF TESTNET}$10000000{$ELSE}{$ENDIF}{$ENDIF};
 
 
 
 
   CT_CalcNewTargetBlocksAverage: Cardinal = 100;
   CT_CalcNewTargetBlocksAverage: Cardinal = 100;
@@ -127,10 +127,10 @@ Const
   CT_Protocol_Upgrade_v3_MinBlock = {$IFDEF PRODUCTION}210000{$ELSE}250{$ENDIF};
   CT_Protocol_Upgrade_v3_MinBlock = {$IFDEF PRODUCTION}210000{$ELSE}250{$ENDIF};
   CT_Protocol_Upgrade_v4_MinBlock = {$IFDEF PRODUCTION}260000{$ELSE}400{$ENDIF};
   CT_Protocol_Upgrade_v4_MinBlock = {$IFDEF PRODUCTION}260000{$ELSE}400{$ENDIF};
   CT_Protocol_Upgrade_v5_MinBlock = {$IFDEF PRODUCTION}378000{$ELSE}500{$ENDIF};
   CT_Protocol_Upgrade_v5_MinBlock = {$IFDEF PRODUCTION}378000{$ELSE}500{$ENDIF};
-  CT_Protocol_Upgrade_v6_MinBlock = {$IFDEF PRODUCTION}999999999{$ELSE}600{$ENDIF}; // TODO: ALLOW V6 activate setting a valid "min block" value
+  CT_Protocol_Upgrade_v6_MinBlock = {$IFDEF PRODUCTION}999999999{$ELSE}999999999{$ENDIF}; // TODO: ALLOW V6 activate setting a valid "min block" value
 
 
 
 
-  CT_MagicNetIdentification = {$IFDEF PRODUCTION}$0A043580{$ELSE}$06000000{$ENDIF};
+  CT_MagicNetIdentification = {$IFDEF PRODUCTION}$0A043580{$ELSE}$05000004{$ENDIF};
 
 
   CT_NetProtocol_Version: Word = 10;
   CT_NetProtocol_Version: Word = 10;
   // IMPORTANT NOTE!!!
   // IMPORTANT NOTE!!!
@@ -141,9 +141,9 @@ Const
 
 
   CT_SafeBoxBankVersion : Word = 3; // Protocol 2 upgraded safebox version from 2 to 3
   CT_SafeBoxBankVersion : Word = 3; // Protocol 2 upgraded safebox version from 2 to 3
 
 
-  CT_MagicIdentificator: String = {$IFDEF PRODUCTION}'PascalCoin'{$ELSE}'PascalCoin_TESTNET_6'{$ENDIF}; //
+  CT_MagicIdentificator: String = {$IFDEF PRODUCTION}'PascalCoin'{$ELSE}'PascalCoinTESTNET_5.Beta.4'{$ENDIF}; //
 
 
-  CT_PascalCoin_Data_Folder : String = {$IFDEF PRODUCTION}'PascalCoin'{$ELSE}'PascalCoin_TESTNET_6'{$ENDIF}; //
+  CT_PascalCoin_Data_Folder : String = {$IFDEF PRODUCTION}'PascalCoin'{$ELSE}'PascalCoin_TESTNET_5.Beta.4'{$ENDIF}; //
 
 
   CT_PseudoOp_Reward = $0;
   CT_PseudoOp_Reward = $0;
   // Value of Operations type in Protocol 1
   // Value of Operations type in Protocol 1
@@ -198,7 +198,7 @@ Const
   CT_OpSubtype_Data_Signer                = 103;
   CT_OpSubtype_Data_Signer                = 103;
   CT_OpSubtype_Data_Receiver              = 104;
   CT_OpSubtype_Data_Receiver              = 104;
 
 
-  CT_ClientAppVersion : String = {$IFDEF PRODUCTION}'5.4.Beta'{$ELSE}{$IFDEF TESTNET}'TESTNET 6 pre 1'{$ELSE}{$ENDIF}{$ENDIF};
+  CT_ClientAppVersion : String = {$IFDEF PRODUCTION}'5.4.Beta'{$ELSE}{$IFDEF TESTNET}'TESTNET 5.4.beta'{$ELSE}{$ENDIF}{$ENDIF};
 
 
   CT_Discover_IPs = {$IFDEF PRODUCTION}'bpascal1.dynamic-dns.net;bpascal2.dynamic-dns.net;pascalcoin1.dynamic-dns.net;pascalcoin2.dynamic-dns.net;pascalcoin1.dns1.us;pascalcoin2.dns1.us;pascalcoin1.dns2.us;pascalcoin2.dns2.us'
   CT_Discover_IPs = {$IFDEF PRODUCTION}'bpascal1.dynamic-dns.net;bpascal2.dynamic-dns.net;pascalcoin1.dynamic-dns.net;pascalcoin2.dynamic-dns.net;pascalcoin1.dns1.us;pascalcoin2.dns1.us;pascalcoin1.dns2.us;pascalcoin2.dns2.us'
                     {$ELSE}'pascaltestnet1.dynamic-dns.net;pascaltestnet2.dynamic-dns.net;pascaltestnet1.dns1.us;pascaltestnet2.dns1.us'{$ENDIF};
                     {$ELSE}'pascaltestnet1.dynamic-dns.net;pascaltestnet2.dynamic-dns.net;pascaltestnet1.dns1.us;pascaltestnet2.dns1.us'{$ENDIF};

+ 16 - 4
src/core/UNode.pas

@@ -124,6 +124,7 @@ Type
     procedure MarkVerifiedECDSASignaturesFromMemPool(newOperationsToValidate : TPCOperationsComp);
     procedure MarkVerifiedECDSASignaturesFromMemPool(newOperationsToValidate : TPCOperationsComp);
     class function NodeVersion : String;
     class function NodeVersion : String;
     class function GetPascalCoinDataFolder : String;
     class function GetPascalCoinDataFolder : String;
+    class procedure SetPascalCoinDataFolder(const ANewDataFolder : String);
   End;
   End;
 
 
   TThreadSafeNodeNotifyEvent = Class(TPCThread)
   TThreadSafeNodeNotifyEvent = Class(TPCThread)
@@ -207,6 +208,7 @@ implementation
 Uses UOpTransaction, UConst, UTime, UCommon, UPCOperationsSignatureValidator, UFolderHelper;
 Uses UOpTransaction, UConst, UTime, UCommon, UPCOperationsSignatureValidator, UFolderHelper;
 
 
 var _Node : TNode;
 var _Node : TNode;
+  _PascalCoinDataFolder : String;
 
 
 { TNode }
 { TNode }
 
 
@@ -652,8 +654,8 @@ begin
   if Not Assigned(_Node) then _Node := Self;
   if Not Assigned(_Node) then _Node := Self;
 end;
 end;
 
 
-class procedure TNode.DecodeIpStringToNodeServerAddressArray(
-  const Ips: String; Var NodeServerAddressArray: TNodeServerAddressArray);
+class procedure TNode.DecodeIpStringToNodeServerAddressArray(const Ips: String;
+  var NodeServerAddressArray: TNodeServerAddressArray);
   Function GetIp(var ips_string : String; var nsa : TNodeServerAddress) : Boolean;
   Function GetIp(var ips_string : String; var nsa : TNodeServerAddress) : Boolean;
   Const CT_IP_CHARS = ['a'..'z','A'..'Z','0'..'9','.','-','_'];
   Const CT_IP_CHARS = ['a'..'z','A'..'Z','0'..'9','.','-','_'];
   var i : Integer;
   var i : Integer;
@@ -829,7 +831,7 @@ begin
   Result := true;
   Result := true;
 end;
 end;
 
 
-function TNode.IsReady(Var CurrentProcess: String): Boolean;
+function TNode.IsReady(var CurrentProcess: String): Boolean;
 var LLockedMempool : TPCOperationsComp;
 var LLockedMempool : TPCOperationsComp;
 begin
 begin
   Result := false;
   Result := false;
@@ -1293,7 +1295,16 @@ end;
 
 
 class function TNode.GetPascalCoinDataFolder: String;
 class function TNode.GetPascalCoinDataFolder: String;
 begin
 begin
-  Result := TFolderHelper.GetDataFolder(CT_PascalCoin_Data_Folder);
+  if (_PascalCoinDataFolder.Trim.Length>0) then begin
+    Result := _PascalCoinDataFolder;
+  end else begin
+    Result := TFolderHelper.GetDataFolder(CT_PascalCoin_Data_Folder);
+  end;
+end;
+
+class procedure TNode.SetPascalCoinDataFolder(const ANewDataFolder: String);
+begin
+  _PascalCoinDataFolder := ANewDataFolder;
 end;
 end;
 
 
 function TNode.LockMempoolRead: TPCOperationsComp;
 function TNode.LockMempoolRead: TPCOperationsComp;
@@ -1600,6 +1611,7 @@ end;
 
 
 initialization
 initialization
   _Node := Nil;
   _Node := Nil;
+  _PascalCoinDataFolder := '';
 finalization
 finalization
   FreeAndNil(_Node);
   FreeAndNil(_Node);
 end.
 end.

+ 2 - 2
src/core/UOpTransaction.pas

@@ -1458,7 +1458,7 @@ begin
     Exit;
     Exit;
   end;
   end;
   if (account_signer.balance<FData.fee) then begin
   if (account_signer.balance<FData.fee) then begin
-    errors := 'Insuficient founds';
+    errors := 'Insuficient funds';
     exit;
     exit;
   end;
   end;
   if (length(FData.payload.payload_raw)>CT_MaxPayloadSize) then begin
   if (length(FData.payload.payload_raw)>CT_MaxPayloadSize) then begin
@@ -2060,7 +2060,7 @@ begin
     Exit;
     Exit;
   end;
   end;
   if (account_signer.balance<FData.fee) then begin
   if (account_signer.balance<FData.fee) then begin
-    errors := 'Insuficient founds';
+    errors := 'Insuficient funds';
     exit;
     exit;
   end;
   end;
   if (length(FData.payload.payload_raw)>CT_MaxPayloadSize) then begin
   if (length(FData.payload.payload_raw)>CT_MaxPayloadSize) then begin

+ 5 - 5
src/core/UPCTemporalFileStream.pas

@@ -41,7 +41,7 @@ Type
 
 
 implementation
 implementation
 
 
-Uses ULog, UNode;
+Uses {$IFDEF HIGHLOG}ULog, {$ENDIF} UNode;
 
 
 { TPCTemporalFileStream }
 { TPCTemporalFileStream }
 
 
@@ -63,18 +63,18 @@ begin
     end;
     end;
     inc(i);
     inc(i);
   until (Not (FileExists(LFileName)) or (i>5000));
   until (Not (FileExists(LFileName)) or (i>5000));
-  TLog.NewLog(ltdebug,ClassName,Format('Creating a new Temporal file Stream: %s',[LFileName]));
+  {$IFDEF HIGHLOG}TLog.NewLog(ltdebug,ClassName,Format('Creating a new Temporal file Stream: %s',[LFileName]));{$ENDIF}
   inherited Create(LFileName,fmCreate+fmShareDenyWrite);
   inherited Create(LFileName,fmCreate+fmShareDenyWrite);
   FTemporalFileName:=LFileName;
   FTemporalFileName:=LFileName;
 end;
 end;
 
 
 destructor TPCTemporalFileStream.Destroy;
 destructor TPCTemporalFileStream.Destroy;
-var LSize : Integer;
+{$IFDEF HIGHLOG}var LSize : Integer;{$ENDIF}
 begin
 begin
-  LSize := Size;
+  {$IFDEF HIGHLOG}LSize := Size;{$ENDIF}
   inherited Destroy;
   inherited Destroy;
   if FTemporalFileName<>'' then begin
   if FTemporalFileName<>'' then begin
-    TLog.NewLog(ltdebug,ClassName,Format('Deleting a Temporal file Stream (%d bytes): %s',[LSize, FTemporalFileName]));
+    {$IFDEF HIGHLOG}TLog.NewLog(ltdebug,ClassName,Format('Deleting a Temporal file Stream (%d bytes): %s',[LSize, FTemporalFileName]));{$ENDIF}
     DeleteFile(FTemporalFileName);
     DeleteFile(FTemporalFileName);
   end;
   end;
 end;
 end;

+ 1 - 0
src/core/URPC.pas

@@ -3558,6 +3558,7 @@ begin
       jso.GetAsVariant('lastcon').Value := nsaarr[i].last_connection;
       jso.GetAsVariant('lastcon').Value := nsaarr[i].last_connection;
       jso.GetAsVariant('attempts').Value := nsaarr[i].total_failed_attemps_to_connect;
       jso.GetAsVariant('attempts').Value := nsaarr[i].total_failed_attemps_to_connect;
     end;
     end;
+    GetResultObject.GetAsVariant('datafolder').Value:=FNode.GetPascalCoinDataFolder;
     Result := True;
     Result := True;
   end else if (method='encodepubkey') then begin
   end else if (method='encodepubkey') then begin
     // Creates a encoded public key based on params
     // Creates a encoded public key based on params

+ 30 - 34
src/core/upcdaemon.pas

@@ -46,6 +46,7 @@ Const
   CT_INI_IDENT_LOWMEMORY = 'LOWMEMORY';
   CT_INI_IDENT_LOWMEMORY = 'LOWMEMORY';
   CT_INI_IDENT_MINPENDINGBLOCKSTODOWNLOADCHECKPOINT = 'MINPENDINGBLOCKSTODOWNLOADCHECKPOINT';
   CT_INI_IDENT_MINPENDINGBLOCKSTODOWNLOADCHECKPOINT = 'MINPENDINGBLOCKSTODOWNLOADCHECKPOINT';
   CT_INI_IDENT_PEERCACHE = 'PEERCACHE';
   CT_INI_IDENT_PEERCACHE = 'PEERCACHE';
+  CT_INI_IDENT_DATA_FOLDER = 'DATAFOLDER';
 
 
 Type
 Type
   { TPCDaemonThread }
   { TPCDaemonThread }
@@ -55,6 +56,7 @@ Type
     FIniFile : TIniFile;
     FIniFile : TIniFile;
     FMaxBlockToRead: Int64;
     FMaxBlockToRead: Int64;
     FLastNodesCacheUpdatedTS : TTickCount;
     FLastNodesCacheUpdatedTS : TTickCount;
+    function GetDataFolder : String;
     procedure OnNetDataReceivedHelloMessage(Sender : TObject);
     procedure OnNetDataReceivedHelloMessage(Sender : TObject);
     procedure OnInitSafeboxProgressNotify(sender : TObject; const message : String; curPos, totalCount : Int64);
     procedure OnInitSafeboxProgressNotify(sender : TObject; const message : String; curPos, totalCount : Int64);
   protected
   protected
@@ -70,7 +72,6 @@ Type
   TPCDaemon = Class(TCustomDaemon)
   TPCDaemon = Class(TCustomDaemon)
   Private
   Private
     FThread : TPCDaemonThread;
     FThread : TPCDaemonThread;
-    Procedure ThreadStopped (Sender : TObject);
   public
   public
     Function Start : Boolean; override;
     Function Start : Boolean; override;
     Function Stop : Boolean; override;
     Function Stop : Boolean; override;
@@ -87,7 +88,6 @@ Type
   TPCDaemonMapper = Class(TCustomDaemonMapper)
   TPCDaemonMapper = Class(TCustomDaemonMapper)
   private
   private
     FLog : TLog;
     FLog : TLog;
-    procedure OnPascalCoinInThreadLog(logtype : TLogType; Time : TDateTime; AThreadID : TThreadID; Const sender, logtext : String);
   protected
   protected
     Procedure DoOnCreate; override;
     Procedure DoOnCreate; override;
     Procedure DoOnDestroy; override;
     Procedure DoOnDestroy; override;
@@ -105,6 +105,19 @@ Var _FLog : TLog;
 
 
 { TPCDaemonThread }
 { TPCDaemonThread }
 
 
+function TPCDaemonThread.GetDataFolder: String;
+Var LIniDataFolder : String;
+begin
+  LIniDataFolder := FIniFile.ReadString(CT_INI_SECTION_GLOBAL,CT_INI_IDENT_DATA_FOLDER,'').Trim;
+  if (LIniDataFolder.Length=0) then begin
+    LIniDataFolder:=TNode.GetPascalCoinDataFolder;
+  end else begin
+    TNode.SetPascalCoinDataFolder(LIniDataFolder);
+  end;
+  ForceDirectories(LIniDataFolder);
+  Result := LIniDataFolder;
+end;
+
 procedure TPCDaemonThread.OnNetDataReceivedHelloMessage(Sender: TObject);
 procedure TPCDaemonThread.OnNetDataReceivedHelloMessage(Sender: TObject);
 Var LNsarr : TNodeServerAddressArray;
 Var LNsarr : TNodeServerAddressArray;
   i : Integer;
   i : Integer;
@@ -154,7 +167,7 @@ var
     TLog.NewLog(ltInfo,ClassName,'RPC server is active on port '+IntToStr(port));
     TLog.NewLog(ltInfo,ClassName,'RPC server is active on port '+IntToStr(port));
     If FIniFile.ReadBool(CT_INI_SECTION_GLOBAL,CT_INI_IDENT_RPC_SAVELOGS,true) then begin
     If FIniFile.ReadBool(CT_INI_SECTION_GLOBAL,CT_INI_IDENT_RPC_SAVELOGS,true) then begin
       FIniFile.WriteBool(CT_INI_SECTION_GLOBAL,CT_INI_IDENT_RPC_SAVELOGS,true);
       FIniFile.WriteBool(CT_INI_SECTION_GLOBAL,CT_INI_IDENT_RPC_SAVELOGS,true);
-      FRPC.LogFileName:= TNode.GetPascalCoinDataFolder+PathDelim+'pascalcoin_rpc.log';
+      FRPC.LogFileName:= GetDataFolder+PathDelim+'pascalcoin_rpc.log';
       TLog.NewLog(ltInfo,ClassName,'Activating RPC logs on file '+FRPC.LogFileName);
       TLog.NewLog(ltInfo,ClassName,'Activating RPC logs on file '+FRPC.LogFileName);
     end else begin
     end else begin
       FIniFile.WriteBool(CT_INI_SECTION_GLOBAL,CT_INI_IDENT_RPC_SAVELOGS,false);
       FIniFile.WriteBool(CT_INI_SECTION_GLOBAL,CT_INI_IDENT_RPC_SAVELOGS,false);
@@ -233,12 +246,10 @@ begin
       // Load Node
       // Load Node
       // Check OpenSSL dll
       // Check OpenSSL dll
       if Not LoadSSLCrypt then begin
       if Not LoadSSLCrypt then begin
-        WriteLn('Cannot load '+SSL_C_LIB);
-        WriteLn('To use this software make sure this file is available on you system or reinstall the application');
         raise Exception.Create('Cannot load '+SSL_C_LIB+#10+'To use this software make sure this file is available on you system or reinstall the application');
         raise Exception.Create('Cannot load '+SSL_C_LIB+#10+'To use this software make sure this file is available on you system or reinstall the application');
       end;
       end;
       TCrypto.InitCrypto;
       TCrypto.InitCrypto;
-      FWalletKeys.WalletFileName := TNode.GetPascalCoinDataFolder+PathDelim+'WalletKeys.dat';
+      FWalletKeys.WalletFileName := GetDataFolder+PathDelim+'WalletKeys.dat';
       // Creating Node:
       // Creating Node:
       FNode := TNode.Node;
       FNode := TNode.Node;
       {$IFDEF TESTNET}
       {$IFDEF TESTNET}
@@ -249,7 +260,7 @@ begin
       Try
       Try
         // Check Database
         // Check Database
         FNode.Bank.StorageClass := TFileStorage;
         FNode.Bank.StorageClass := TFileStorage;
-        TFileStorage(FNode.Bank.Storage).DatabaseFolder := TNode.GetPascalCoinDataFolder+PathDelim+'Data';
+        TFileStorage(FNode.Bank.Storage).DatabaseFolder := GetDataFolder+PathDelim+'Data';
         TFileStorage(FNode.Bank.Storage).LowMemoryUsage := FIniFile.ReadBool(CT_INI_SECTION_GLOBAL,CT_INI_IDENT_LOWMEMORY,False);
         TFileStorage(FNode.Bank.Storage).LowMemoryUsage := FIniFile.ReadBool(CT_INI_SECTION_GLOBAL,CT_INI_IDENT_LOWMEMORY,False);
         // By default daemon will not download checkpoint except if specified on INI file
         // By default daemon will not download checkpoint except if specified on INI file
         TNetData.NetData.MinFutureBlocksToDownloadNewSafebox := FIniFile.ReadInteger(CT_INI_SECTION_GLOBAL,CT_INI_IDENT_MINPENDINGBLOCKSTODOWNLOADCHECKPOINT,0);
         TNetData.NetData.MinFutureBlocksToDownloadNewSafebox := FIniFile.ReadInteger(CT_INI_SECTION_GLOBAL,CT_INI_IDENT_MINPENDINGBLOCKSTODOWNLOADCHECKPOINT,0);
@@ -268,7 +279,7 @@ begin
         Try
         Try
           Repeat
           Repeat
             Sleep(100);
             Sleep(100);
-          Until Terminated;
+          Until (Terminated) or (Application.Terminated);
         finally
         finally
           FreeAndNil(FMinerServer);
           FreeAndNil(FMinerServer);
         end;
         end;
@@ -313,30 +324,26 @@ end;
 
 
 { TPCDaemon }
 { TPCDaemon }
 
 
-procedure TPCDaemon.ThreadStopped(Sender: TObject);
-begin
-  FreeAndNil(FThread);
-end;
-
 function TPCDaemon.Start: Boolean;
 function TPCDaemon.Start: Boolean;
 begin
 begin
   Result:=inherited Start;
   Result:=inherited Start;
   TLog.NewLog(ltinfo,ClassName,'Daemon Start '+BoolToStr(Result));
   TLog.NewLog(ltinfo,ClassName,'Daemon Start '+BoolToStr(Result));
   FThread:=TPCDaemonThread.Create;
   FThread:=TPCDaemonThread.Create;
-  FThread.OnTerminate:=@ThreadStopped;
-  FThread.FreeOnTerminate:=False;
+  FThread.FreeOnTerminate:=True;
   if (Application.HasOption('b','block')) then begin
   if (Application.HasOption('b','block')) then begin
     FThread.MaxBlockToRead:=StrToInt64Def(Application.GetOptionValue('b','block'),$FFFFFFFF);
     FThread.MaxBlockToRead:=StrToInt64Def(Application.GetOptionValue('b','block'),$FFFFFFFF);
     TLog.NewLog(ltinfo,ClassName,'Max block to read: '+IntToStr(FThread.MaxBlockToRead));
     TLog.NewLog(ltinfo,ClassName,'Max block to read: '+IntToStr(FThread.MaxBlockToRead));
   end;
   end;
-  FThread.Resume;
+  FThread.Start;
 end;
 end;
 
 
 function TPCDaemon.Stop: Boolean;
 function TPCDaemon.Stop: Boolean;
 begin
 begin
   Result:=inherited Stop;
   Result:=inherited Stop;
-  TLog.NewLog(ltinfo,ClassName,'Daemon Stop: '+BoolToStr(Result));
+  TLog.NewLog(ltinfo,ClassName,'Daemon Stop Start');
   FThread.Terminate;
   FThread.Terminate;
+  FThread.WaitFor;
+  TLog.NewLog(ltinfo,ClassName,'Daemon Stop Finished');
 end;
 end;
 
 
 function TPCDaemon.Pause: Boolean;
 function TPCDaemon.Pause: Boolean;
@@ -362,8 +369,10 @@ end;
 function TPCDaemon.ShutDown: Boolean;
 function TPCDaemon.ShutDown: Boolean;
 begin
 begin
   Result:=inherited ShutDown;
   Result:=inherited ShutDown;
-  TLog.NewLog(ltinfo,ClassName,'Daemon Shutdown: '+BoolToStr(Result));
+  TLog.NewLog(ltinfo,ClassName,'Daemon Shutdown Start');
   FThread.Terminate;
   FThread.Terminate;
+  FThread.WaitFor;
+  TLog.NewLog(ltinfo,ClassName,'Daemon Shutdown Finished');
 end;
 end;
 
 
 function TPCDaemon.Install: Boolean;
 function TPCDaemon.Install: Boolean;
@@ -380,40 +389,27 @@ end;
 
 
 { TPCDaemonMapper }
 { TPCDaemonMapper }
 
 
-procedure TPCDaemonMapper.OnPascalCoinInThreadLog(logtype: TLogType;
-  Time: TDateTime; AThreadID: TThreadID; const sender, logtext: String);
-Var s : AnsiString;
-begin
-//  If Not SameText(sender,TPCDaemonThread.ClassName) then exit;
-  If logtype in [lterror,ltinfo] then begin
-    if AThreadID=MainThreadID then s := ' MAIN:' else s:=' TID:';
-    WriteLn(formatDateTime('dd/mm/yyyy hh:nn:ss.zzz',Time)+s+IntToHex(PtrInt(AThreadID),8)+' ['+CT_LogType[Logtype]+'] <'+sender+'> '+logtext);
-  end;
-end;
-
 procedure TPCDaemonMapper.DoOnCreate;
 procedure TPCDaemonMapper.DoOnCreate;
 Var D : TDaemonDef;
 Var D : TDaemonDef;
 begin
 begin
   inherited DoOnCreate;
   inherited DoOnCreate;
-  WriteLn('');
-  WriteLn(formatDateTime('dd/mm/yyyy hh:nn:ss.zzz',now)+' Starting PascalCoin server');
   FLog := TLog.Create(Nil);
   FLog := TLog.Create(Nil);
-  FLog.OnInThreadNewLog:=@OnPascalCoinInThreadLog;
   _FLog := FLog;
   _FLog := FLog;
   D:=DaemonDefs.Add as TDaemonDef;
   D:=DaemonDefs.Add as TDaemonDef;
-  D.DisplayName:='Pascal Coin Daemon';
+  D.DisplayName:='PascalCoin Daemon';
   D.Name:='PascalCoinDaemon';
   D.Name:='PascalCoinDaemon';
   D.DaemonClassName:='TPCDaemon';
   D.DaemonClassName:='TPCDaemon';
+  D.Options:=[doAllowStop];
   D.WinBindings.ServiceType:=stWin32;
   D.WinBindings.ServiceType:=stWin32;
 end;
 end;
 
 
 procedure TPCDaemonMapper.DoOnDestroy;
 procedure TPCDaemonMapper.DoOnDestroy;
 begin
 begin
+  inherited DoOnDestroy;
   If Assigned(FLog) then begin
   If Assigned(FLog) then begin
     FLog.OnInThreadNewLog:=Nil;
     FLog.OnInThreadNewLog:=Nil;
     FreeAndNil(FLog);
     FreeAndNil(FLog);
   end;
   end;
-  inherited DoOnDestroy;
 end;
 end;
 
 
 end.
 end.

+ 5 - 2
src/gui-classic/UFRMAbout.pas

@@ -69,7 +69,10 @@ uses
 {$IFDEF Use_OpenSSL}
 {$IFDEF Use_OpenSSL}
   UOpenSSL,
   UOpenSSL,
 {$ENDIF}
 {$ENDIF}
-  UNode,gnugettext;
+{$IFDEF USE_GNUGETTEXT}
+  gnugettext,
+{$ENDIF}
+  UNode;
 
 
 {$IFnDEF FPC}
 {$IFnDEF FPC}
   {$R *.dfm}
   {$R *.dfm}
@@ -79,7 +82,7 @@ uses
 
 
 procedure TFRMAbout.FormCreate(Sender: TObject);
 procedure TFRMAbout.FormCreate(Sender: TObject);
 begin
 begin
-  TranslateComponent(self);
+  {$IFDEF USE_GNUGETTEXT}TranslateComponent(self);{$ENDIF}
   //
   //
   lblBuild.Caption :=  'Build: '+CT_ClientAppVersion+' OpenSSL: '+{$IFDEF Use_OpenSSL}IntToHex(OpenSSLVersion,8){$ELSE}'NONE'{$ENDIF}+' Compiler: '{$IFDEF FPC}+'FPC'{$IFDEF CPU32}+' 32b'{$ELSE}+' 64b'{$ENDIF}{$ELSE}+'Delphi'{$IFDEF CPU32BITS}+' 32b'{$ELSE}+' 64b'{$ENDIF}{$ENDIF};
   lblBuild.Caption :=  'Build: '+CT_ClientAppVersion+' OpenSSL: '+{$IFDEF Use_OpenSSL}IntToHex(OpenSSLVersion,8){$ELSE}'NONE'{$ENDIF}+' Compiler: '{$IFDEF FPC}+'FPC'{$IFDEF CPU32}+' 32b'{$ELSE}+' 64b'{$ENDIF}{$ELSE}+'Delphi'{$IFDEF CPU32BITS}+' 32b'{$ELSE}+' 64b'{$ENDIF}{$ENDIF};
   lblProtocolVersion.Caption := Format('BlockChain Protocol: %d (%d)  -  Net Protocol: %d (%d)',[TNode.Node.Bank.SafeBox.CurrentProtocol,CT_BlockChain_Protocol_Available,
   lblProtocolVersion.Caption := Format('BlockChain Protocol: %d (%d)  -  Net Protocol: %d (%d)',[TNode.Node.Bank.SafeBox.CurrentProtocol,CT_BlockChain_Protocol_Available,

+ 2 - 2
src/gui-classic/UFRMNewPrivateKeyType.pas

@@ -57,7 +57,7 @@ type
 implementation
 implementation
 
 
 uses
 uses
-  UAccounts, UConst,gnugettext ;
+  {$IFDEF USE_GNUGETTEXT}gnugettext,{$ENDIF}UAccounts, UConst;
 
 
 {$IFnDEF FPC}
 {$IFnDEF FPC}
   {$R *.dfm}
   {$R *.dfm}
@@ -82,7 +82,7 @@ procedure TFRMNewPrivateKeyType.FormCreate(Sender: TObject);
 Var l : TList<Word>;
 Var l : TList<Word>;
   i : Integer;
   i : Integer;
 begin
 begin
-  TranslateComponent(self);
+  {$IFDEF USE_GNUGETTEXT}TranslateComponent(self);{$ENDIF}
   //
   //
   FGeneratedPrivateKey := Nil;
   FGeneratedPrivateKey := Nil;
   FWalletKeys := Nil;
   FWalletKeys := Nil;

+ 2 - 2
src/gui-classic/UFRMNodesIp.pas

@@ -54,7 +54,7 @@ type
 implementation
 implementation
 
 
 uses
 uses
-  UNetProtocol, UNode, UConst, USettings,gnugettext;
+  {$IFDEF USE_GNUGETTEXT}gnugettext,{$ENDIF}UNetProtocol, UNode, UConst, USettings;
 
 
 {$IFnDEF FPC}
 {$IFnDEF FPC}
   {$R *.dfm}
   {$R *.dfm}
@@ -112,7 +112,7 @@ end;
 
 
 procedure TFRMNodesIp.FormCreate(Sender: TObject);
 procedure TFRMNodesIp.FormCreate(Sender: TObject);
 begin
 begin
-  TranslateComponent(self);
+  {$IFDEF USE_GNUGETTEXT}TranslateComponent(self);{$ENDIF}
   //
   //
   FAppParams := Nil;
   FAppParams := Nil;
   PrepareData;
   PrepareData;

+ 3 - 3
src/gui-classic/UFRMOperation.pas

@@ -191,8 +191,8 @@ type
 implementation
 implementation
 
 
 uses
 uses
-  UConst, UOpTransaction, UFRMNewPrivateKeyType, UFRMWalletKeys, UFRMHashLock,
-  UCommon, ULog, UGUIUtils,gnugettext;
+  {$IFDEF USE_GNUGETTEXT}gnugettext,{$ENDIF}UConst, UOpTransaction, UFRMNewPrivateKeyType, UFRMWalletKeys, UFRMHashLock,
+  UCommon, ULog, UGUIUtils;
 
 
 {$IFnDEF FPC}
 {$IFnDEF FPC}
   {$R *.dfm}
   {$R *.dfm}
@@ -530,7 +530,7 @@ end;
 
 
 procedure TFRMOperation.FormCreate(Sender: TObject);
 procedure TFRMOperation.FormCreate(Sender: TObject);
 begin
 begin
-  Translatecomponent(self);
+  {$IFDEF USE_GNUGETTEXT}TranslateComponent(self);{$ENDIF}
   FDisabled := false;
   FDisabled := false;
   FWalletKeys := Nil;
   FWalletKeys := Nil;
   FSenderAccounts := TOrderedCardinalList.Create;
   FSenderAccounts := TOrderedCardinalList.Create;

+ 5 - 2
src/gui-classic/UFRMPascalCoinWalletConfig.pas

@@ -97,7 +97,8 @@ type
 
 
 implementation
 implementation
 
 
-uses UConst, UAccounts, ULog, UCrypto, UNode, USettings, UGUIUtils, UNetProtocol, UFRMSelectLanguage,gnugettext;
+uses
+  {$IFDEF USE_GNUGETTEXT}gnugettext, UFRMSelectLanguage, {$ENDIF}UConst, UAccounts, ULog, UCrypto, UNode, USettings, UGUIUtils, UNetProtocol;
 
 
 {$IFnDEF FPC}
 {$IFnDEF FPC}
   {$R *.dfm}
   {$R *.dfm}
@@ -198,7 +199,7 @@ end;
 
 
 procedure TFRMPascalCoinWalletConfig.FormCreate(Sender: TObject);
 procedure TFRMPascalCoinWalletConfig.FormCreate(Sender: TObject);
 begin
 begin
-  TranslateComponent(self);
+  {$IFDEF USE_GNUGETTEXT}TranslateComponent(self);{$ENDIF}
   //
   //
   lblDefaultInternetServerPort.Caption := Format('(Default %d)',[CT_NetServer_Port]);
   lblDefaultInternetServerPort.Caption := Format('(Default %d)',[CT_NetServer_Port]);
   udInternetServerPort.Position := CT_NetServer_Port;
   udInternetServerPort.Position := CT_NetServer_Port;
@@ -220,6 +221,7 @@ end;
 
 
 procedure TFRMPascalCoinWalletConfig.bbChangeLanguageClick(Sender: TObject);
 procedure TFRMPascalCoinWalletConfig.bbChangeLanguageClick(Sender: TObject);
 begin
 begin
+  {$IFDEF USE_GNUGETTEXT}
    fNewUILanguage := AppParams.ParamByName[CT_PARAM_UILanguage].GetAsString(GetCurrentLanguage);
    fNewUILanguage := AppParams.ParamByName[CT_PARAM_UILanguage].GetAsString(GetCurrentLanguage);
    fNewUILanguage := SelectUILanguage(fNewUILanguage);
    fNewUILanguage := SelectUILanguage(fNewUILanguage);
    if fNewUILanguage<>AppParams.ParamByName[CT_PARAM_UILanguage].GetAsString(GetCurrentLanguage) then // new language selected
    if fNewUILanguage<>AppParams.ParamByName[CT_PARAM_UILanguage].GetAsString(GetCurrentLanguage) then // new language selected
@@ -227,6 +229,7 @@ begin
      UseLanguage(fNewUILanguage);
      UseLanguage(fNewUILanguage);
      RetranslateComponent(Self);
      RetranslateComponent(Self);
    end;
    end;
+  {$ENDIF}
 end;
 end;
 
 
 procedure TFRMPascalCoinWalletConfig.SetAppParams(const Value: TAppParams);
 procedure TFRMPascalCoinWalletConfig.SetAppParams(const Value: TAppParams);

+ 2 - 2
src/gui-classic/UFRMPayloadDecoder.pas

@@ -106,7 +106,7 @@ implementation
   {$R *.lfm}
   {$R *.lfm}
 {$ENDIF}
 {$ENDIF}
 
 
-Uses UNode, UTime, UPCEncryption, UAccounts, UFRMMemoText, UBaseTypes,gnugettext;
+Uses {$IFDEF USE_GNUGETTEXT}gnugettext,{$ENDIF}UNode, UTime, UPCEncryption, UAccounts, UFRMMemoText, UBaseTypes;
 
 
 { TFRMPayloadDecoder }
 { TFRMPayloadDecoder }
 
 
@@ -220,7 +220,7 @@ end;
 
 
 procedure TFRMPayloadDecoder.FormCreate(Sender: TObject);
 procedure TFRMPayloadDecoder.FormCreate(Sender: TObject);
 begin
 begin
-  TranslateComponent(self);
+  {$IFDEF USE_GNUGETTEXT}TranslateComponent(self);{$ENDIF}
   //
   //
   FSemaphor := true;
   FSemaphor := true;
   try
   try

+ 1 - 1
src/gui-classic/UFRMSelectLanguage.pas

@@ -7,7 +7,7 @@ unit UFRMSelectLanguage;
 interface
 interface
 
 
 uses
 uses
-   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, Buttons, StdCtrls,gnugettext;
+  gnugettext,Classes, SysUtils, Forms, Controls, Graphics, Dialogs, Buttons, StdCtrls;
 
 
 type
 type
 
 

+ 6 - 4
src/gui-classic/UFRMWallet.pas

@@ -327,7 +327,7 @@ implementation
   {$R *.lfm}
   {$R *.lfm}
 {$ENDIF}
 {$ENDIF}
 
 
-Uses UFolderHelper,gnugettext,
+Uses UFolderHelper,{$IFDEF USE_GNUGETTEXT}gnugettext,{$ENDIF}
 {$IFDEF Use_OpenSSL}
 {$IFDEF Use_OpenSSL}
   UOpenSSL,
   UOpenSSL,
 {$ENDIF}
 {$ENDIF}
@@ -1299,7 +1299,7 @@ end;
 procedure TFRMWallet.FormCreate(Sender: TObject);
 procedure TFRMWallet.FormCreate(Sender: TObject);
 Var i : Integer;
 Var i : Integer;
 begin
 begin
-  TranslateComponent(Self);
+  {$IFDEF USE_GNUGETTEXT}TranslateComponent(self);{$ENDIF}
   //
   //
   {$IFNDEF FPC}
   {$IFNDEF FPC}
   {$IFDEF TESTNET}
   {$IFDEF TESTNET}
@@ -1369,10 +1369,12 @@ begin
   FBlockChainGrid.DrawGrid := dgBlockChainExplorer;
   FBlockChainGrid.DrawGrid := dgBlockChainExplorer;
   // FWalletKeys.OnChanged.Add( OnWalletChanged );
   // FWalletKeys.OnChanged.Add( OnWalletChanged );
   LoadAppParams;
   LoadAppParams;
+  {$IFDEF USE_GNUGETTEXT}
   // use language from the params and retranslate if needed
   // use language from the params and retranslate if needed
   // might be better to move this a bit earlier in the formcreate routine
   // might be better to move this a bit earlier in the formcreate routine
   UseLanguage(FAppParams.ParamByName[CT_PARAM_UILanguage].GetAsString(GetCurrentLanguage));
   UseLanguage(FAppParams.ParamByName[CT_PARAM_UILanguage].GetAsString(GetCurrentLanguage));
-  RetranslateComponent(Self);
+  RetranslateComponent(self);
+  {$ENDIF}
   //
   //
   UpdatePrivateKeys;
   UpdatePrivateKeys;
   UpdateBlockChainState;
   UpdateBlockChainState;
@@ -2053,7 +2055,7 @@ begin
     if ShowModal=MrOk then begin
     if ShowModal=MrOk then begin
       SaveAppParams;
       SaveAppParams;
       UpdateConfigChanged;
       UpdateConfigChanged;
-      RetranslateComponent(self);
+      {$IFDEF USE_GNUGETTEXT}RetranslateComponent(self);{$ENDIF}
     end;
     end;
   finally
   finally
     free;
     free;

+ 3 - 2
src/gui-classic/UFRMWalletKeys.pas

@@ -95,8 +95,9 @@ uses
 {$ELSE}
 {$ELSE}
   LCLIntf, LCLType,
   LCLIntf, LCLType,
 {$ENDIF}
 {$ENDIF}
+  {$IFDEF USE_GNUGETTEXT}gnugettext,{$ENDIF}
   UCrypto, UAccounts, UFRMNewPrivateKeyType, UBaseTypes, UPCEncryption,
   UCrypto, UAccounts, UFRMNewPrivateKeyType, UBaseTypes, UPCEncryption,
-  UPCDataTypes, UCommon, UGUIUtils,gnugettext;
+  UPCDataTypes, UCommon, UGUIUtils;
 
 
 {$IFnDEF FPC}
 {$IFnDEF FPC}
   {$R *.dfm}
   {$R *.dfm}
@@ -493,7 +494,7 @@ end;
 
 
 procedure TFRMWalletKeys.FormCreate(Sender: TObject);
 procedure TFRMWalletKeys.FormCreate(Sender: TObject);
 begin
 begin
-  Translatecomponent(self);
+  {$IFDEF USE_GNUGETTEXT}TranslateComponent(self);{$ENDIF}
   lbWalletKeys.Sorted := true;
   lbWalletKeys.Sorted := true;
   FWalletKeys := Nil;
   FWalletKeys := Nil;
   UpdateWalletKeys;
   UpdateWalletKeys;

+ 6 - 2
src/pascalcoin_daemon.ini

@@ -40,8 +40,12 @@ RPC_SERVERMINER_B58_PUBKEY=
 RPC_SERVERMINER_MAX_CONNECTIONS=1000
 RPC_SERVERMINER_MAX_CONNECTIONS=1000
 ;RPC_SERVERMINER_MAX_OPERATIONS_PER_BLOCK : Integer
 ;RPC_SERVERMINER_MAX_OPERATIONS_PER_BLOCK : Integer
 ;Max operations included per block
 ;Max operations included per block
-RPC_SERVERMINER_MAX_OPERATIONS_PER_BLOCK=10000
+RPC_SERVERMINER_MAX_OPERATIONS_PER_BLOCK=
 ;RPC_SERVERMINER_MAX_ZERO_FEE_OPERATIONS : Integer
 ;RPC_SERVERMINER_MAX_ZERO_FEE_OPERATIONS : Integer
 ;Max operations without fee that can be included in a block
 ;Max operations without fee that can be included in a block
 ;Note: Operations with fee>0 are processed first (have more priority)
 ;Note: Operations with fee>0 are processed first (have more priority)
-RPC_SERVERMINER_MAX_ZERO_FEE_OPERATIONS=4000
+RPC_SERVERMINER_MAX_ZERO_FEE_OPERATIONS=
+;DATAFOLDER : String
+;Allow define folder to store data of PascalCoin (Blockchain, Safebox, WalletKeys file, Temporal files ...)
+;If empty will use default folder $HOME/PascalCoin (Each OS will assigna a different $HOME folder, AppData for Windows...)
+DATAFOLDER=

+ 10 - 2
src/pascalcoin_daemon.lpi

@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <?xml version="1.0" encoding="UTF-8"?>
 <CONFIG>
 <CONFIG>
   <ProjectOptions>
   <ProjectOptions>
-    <Version Value="10"/>
+    <Version Value="11"/>
     <PathDelim Value="\"/>
     <PathDelim Value="\"/>
     <General>
     <General>
       <Flags>
       <Flags>
@@ -25,10 +25,18 @@
     </PublishOptions>
     </PublishOptions>
     <RunParams>
     <RunParams>
       <local>
       <local>
-        <FormatVersion Value="1"/>
         <CommandLineParams Value="-r"/>
         <CommandLineParams Value="-r"/>
         <Display Use="True" Value=""/>
         <Display Use="True" Value=""/>
       </local>
       </local>
+      <FormatVersion Value="2"/>
+      <Modes Count="1">
+        <Mode0 Name="default">
+          <local>
+            <CommandLineParams Value="-r"/>
+            <Display Use="True" Value=""/>
+          </local>
+        </Mode0>
+      </Modes>
     </RunParams>
     </RunParams>
     <Units Count="1">
     <Units Count="1">
       <Unit0>
       <Unit0>

+ 19 - 0
src/pascalcoin_daemon.pp

@@ -11,11 +11,30 @@ uses
   Classes, daemonapp,
   Classes, daemonapp,
   UCrypto, upcdaemon;
   UCrypto, upcdaemon;
 
 
+Type
+
+  { TDaemonMainLoop }
+
+  TDaemonMainLoop = Class
+  public
+    Class procedure DaemonMainLoop;
+  end;
+
+{ TDaemonMainLoop }
+
+class procedure TDaemonMainLoop.DaemonMainLoop;
+begin
+  while not Application.Terminated do begin
+    CheckSynchronize(10);
+  end;
+end;
 
 
 begin
 begin
   Application.Title:='PascalCoin Daemon application';
   Application.Title:='PascalCoin Daemon application';
+  IsConsole:=False;
   RegisterDaemonClass(TPCDaemon);
   RegisterDaemonClass(TPCDaemon);
   RegisterDaemonMapper(TPCDaemonMapper);
   RegisterDaemonMapper(TPCDaemonMapper);
+  Application.GUIMainLoop:[email protected];
   TCrypto.InitCrypto;
   TCrypto.InitCrypto;
   Application.Run;
   Application.Run;
 end.
 end.

+ 5 - 1
src/pascalcoin_wallet_classic.dpr

@@ -4,6 +4,8 @@ program PascalCoin_Wallet_Classic;
   {$MODE Delphi}
   {$MODE Delphi}
 {$ENDIF}
 {$ENDIF}
 
 
+{$I ./config.inc}
+
 uses
 uses
   {$IFnDEF FPC}
   {$IFnDEF FPC}
   {$ELSE}
   {$ELSE}
@@ -47,7 +49,9 @@ uses
   UFRMNodesIp in 'gui-classic\UFRMNodesIp.pas' {FRMNodesIp},
   UFRMNodesIp in 'gui-classic\UFRMNodesIp.pas' {FRMNodesIp},
   UFRMOperation in 'gui-classic\UFRMOperation.pas' {FRMOperation},
   UFRMOperation in 'gui-classic\UFRMOperation.pas' {FRMOperation},
   UFRMOperationsExplorer in 'gui-classic\UFRMOperationsExplorer.pas' {FRMOperationsExplorer},
   UFRMOperationsExplorer in 'gui-classic\UFRMOperationsExplorer.pas' {FRMOperationsExplorer},
-  UFRMSelectLanguage in 'gui-classic\UFRMSelectLanguage.pas',
+  {$IFDEF USE_GNUGETTEXT}
+  UFRMSelectLanguage in 'gui-classic\UFRMSelectLanguage.pas' {FRMChangeLanguage},
+  {$ENDIF}
   UFRMPascalCoinWalletConfig in 'gui-classic\UFRMPascalCoinWalletConfig.pas' {FRMPascalCoinWalletConfig},
   UFRMPascalCoinWalletConfig in 'gui-classic\UFRMPascalCoinWalletConfig.pas' {FRMPascalCoinWalletConfig},
   UFRMPayloadDecoder in 'gui-classic\UFRMPayloadDecoder.pas' {FRMPayloadDecoder},
   UFRMPayloadDecoder in 'gui-classic\UFRMPayloadDecoder.pas' {FRMPayloadDecoder},
   UFRMRandomOperations in 'gui-classic\UFRMRandomOperations.pas' {FRMRandomOperations},
   UFRMRandomOperations in 'gui-classic\UFRMRandomOperations.pas' {FRMRandomOperations},

+ 1 - 8
src/pascalcoin_wallet_classic.lpi

@@ -42,7 +42,7 @@
         <PackageName Value="LCL"/>
         <PackageName Value="LCL"/>
       </Item1>
       </Item1>
     </RequiredPackages>
     </RequiredPackages>
-    <Units Count="38">
+    <Units Count="37">
       <Unit0>
       <Unit0>
         <Filename Value="pascalcoin_wallet_classic.dpr"/>
         <Filename Value="pascalcoin_wallet_classic.dpr"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
@@ -222,13 +222,6 @@
         <HasResources Value="True"/>
         <HasResources Value="True"/>
         <ResourceBaseClass Value="Form"/>
         <ResourceBaseClass Value="Form"/>
       </Unit36>
       </Unit36>
-      <Unit37>
-        <Filename Value="gui-classic\UFRMSelectLanguage.pas"/>
-        <IsPartOfProject Value="True"/>
-        <ComponentName Value="FRMChangeLanguage"/>
-        <HasResources Value="True"/>
-        <ResourceBaseClass Value="Form"/>
-      </Unit37>
     </Units>
     </Units>
   </ProjectOptions>
   </ProjectOptions>
   <CompilerOptions>
   <CompilerOptions>

+ 1 - 1
src/tests/PascalCoinUnitTests.lpr

@@ -5,7 +5,7 @@ program UPascalCoinUnitTests;
 uses
 uses
   Interfaces, Forms, GuiTestRunner, UCommon.Collections, UCommon.Tests,
   Interfaces, Forms, GuiTestRunner, UCommon.Collections, UCommon.Tests,
   UCommon.Collections.Tests, UMemory.Tests, UThread.Tests, URandomHash.Tests,
   UCommon.Collections.Tests, UMemory.Tests, UThread.Tests, URandomHash.Tests,
-  URandomHash2.Tests, URandomHash;
+  URandomHash2.Tests, URandomHash, ubasetypes.tests;
 
 
 {$R *.res}
 {$R *.res}
 
 

+ 60 - 0
src/tests/ubasetypes.tests.pas

@@ -0,0 +1,60 @@
+unit UBaseTypes.Tests;
+
+{$mode delphi}
+{$H+}
+{$modeswitch nestedprocvars}
+
+interface
+
+uses
+  Classes, SysUtils, fpcunit,
+  testregistry,
+  UBaseTypes;
+
+type
+
+  { TBytesBufferTest }
+
+  TBytesBufferTest = class(TTestCase)
+    published
+      procedure Test_SaveToStream;
+  end;
+
+implementation
+
+{ TBytesBufferTest }
+
+procedure TBytesBufferTest.Test_SaveToStream;
+var Lbb, Lbb2 : TBytesBuffer;
+  LStream : TStream;
+  LBuffer : TBytes;
+  i : Integer;
+begin
+  SetLength(LBuffer,1000 + Random(1000) );
+  for i:= 0 to High(LBuffer) do begin
+    LBuffer[i] := Random(250)+1;
+  end;
+  Lbb := TBytesBuffer.Create(Random(1000)+100);
+  Lbb.Add(LBuffer);
+  Lbb2 := TBytesBuffer.CreateCopy(Lbb);
+  LStream := TMemoryStream.Create;
+  try
+    Lbb.SaveToStream(LStream);
+    Self.AssertEquals('T1',0,Lbb.Compare(Lbb2));
+    Self.AssertEquals('T2',0,Lbb.Compare(LStream));
+    Lbb2.Clear;
+    Lbb2.LoadFromStream(LStream);
+    Self.AssertEquals('T3',0,Lbb.Compare(Lbb2));
+  finally
+    Lbb.Free;
+    Lbb2.Free;
+  end;
+end;
+
+
+initialization
+  Randomize;
+  RegisterTest(TBytesBufferTest);
+end.
+
+