Преглед изворни кода

Merge pull request #23 from PascalCoinDev/master

Version 5.3
Pascal Coin пре 5 година
родитељ
комит
f33df61aa5

+ 5 - 0
CHANGELOG.md

@@ -1,5 +1,10 @@
 # Changelog
 # Changelog
 
 
+## Build 5.3.0 - 2020-03-12
+- Fixed "out of memory" error when downloading Safebox
+- Fixed freeze bug on GUI when updating accounts grid
+- Minor improvements for testing
+
 ## Build 5.2.0 - 2020-02-11
 ## Build 5.2.0 - 2020-02-11
 - Mandatory upgrade due fixes some important security bugs
 - Mandatory upgrade due fixes some important security bugs
 - Fixed CryptoLib4Pascal multithreading bug
 - Fixed CryptoLib4Pascal multithreading bug

+ 6 - 1
src/config.inc

@@ -57,6 +57,11 @@
 
 
   // This will allow check safebox names list. Warning: This will slow app
   // This will allow check safebox names list. Warning: This will slow app
   {.$DEFINE Check_Safebox_Names_Consistency}
   {.$DEFINE Check_Safebox_Names_Consistency}
+  
+  // This will assume that PoW on old protocols are true and will not check, usefull after enough time to increase validation speed. 
+  // Warning: Use only on versions after enough time since last protocol upgrade and non main-node versions
+  {.$DEFINE ASSUME_VALID_POW_OLD_PROTOCOLS}
+  
 
 
 { ********************************************************************
 { ********************************************************************
   Don't touch more code, it will addapt based on your preferences
   Don't touch more code, it will addapt based on your preferences
@@ -66,7 +71,7 @@
 ERROR: You must select ONLY ONE option: PRODUCTION or TESTNET
 ERROR: You must select ONLY ONE option: PRODUCTION or TESTNET
 {$ENDIF}{$ELSE}{$DEFINE PRODUCTION}{$ENDIF}
 {$ENDIF}{$ELSE}{$DEFINE PRODUCTION}{$ENDIF}
 
 
-{$IF (not Defined(Use_OpenSSL)) or (not Defined(Use_CryptoLib4Pascal))}
+{$IF (not Defined(Use_OpenSSL)) and (not Defined(Use_CryptoLib4Pascal))}
   {$DEFINE Use_OpenSSL}
   {$DEFINE Use_OpenSSL}
   {$UNDEF Use_CryptoLib4Pascal}
   {$UNDEF Use_CryptoLib4Pascal}
 {$ENDIF}
 {$ENDIF}

+ 15 - 0
src/core/UAccounts.pas

@@ -828,6 +828,10 @@ var LTmp : TPCHardcodedRandomHashTable;
   LInternalHardcodedSha256 : TRawBytes;
   LInternalHardcodedSha256 : TRawBytes;
 begin
 begin
   Result := False;
   Result := False;
+  {$IFDEF ASSUME_VALID_POW_OLD_PROTOCOLS}
+  // In this case will not use Hardcoded RandomHash Table
+  Exit;
+  {$ENDIF}
   If Not FileExists(AHardcodedFileName) then begin
   If Not FileExists(AHardcodedFileName) then begin
     TLog.NewLog(ltdebug,ClassName,Format('Hardcoded RandomHash from file not found:%s',
     TLog.NewLog(ltdebug,ClassName,Format('Hardcoded RandomHash from file not found:%s',
       [AHardcodedFileName] ));
       [AHardcodedFileName] ));
@@ -3383,7 +3387,11 @@ begin
               // For TESTNET increase speed purposes, will only check latests blocks
               // For TESTNET increase speed purposes, will only check latests blocks
             if ((iblock + (CT_BankToDiskEveryNBlocks * 10)) >= sbHeader.blockscount) then begin
             if ((iblock + (CT_BankToDiskEveryNBlocks * 10)) >= sbHeader.blockscount) then begin
             {$ENDIF}
             {$ENDIF}
+              {$IFDEF ASSUME_VALID_POW_OLD_PROTOCOLS}
+              LAddToMultiThreadOperationsBlockValidator := (LUseMultiThreadOperationsBlockValidator) and (LBlock.blockchainInfo.protocol_version>=CT_PROTOCOL_5) and (Assigned(LPCOperationsBlockValidator));
+              {$ELSE}
               LAddToMultiThreadOperationsBlockValidator := (LUseMultiThreadOperationsBlockValidator) and (LBlock.blockchainInfo.protocol_version>=CT_PROTOCOL_4) and (Assigned(LPCOperationsBlockValidator));
               LAddToMultiThreadOperationsBlockValidator := (LUseMultiThreadOperationsBlockValidator) and (LBlock.blockchainInfo.protocol_version>=CT_PROTOCOL_4) and (Assigned(LPCOperationsBlockValidator));
+              {$ENDIF}
               If not IsValidNewOperationsBlock(LBlock.blockchainInfo,False,Not LAddToMultiThreadOperationsBlockValidator,aux_errors) then begin
               If not IsValidNewOperationsBlock(LBlock.blockchainInfo,False,Not LAddToMultiThreadOperationsBlockValidator,aux_errors) then begin
                 errors := errors + ' > ' + aux_errors;
                 errors := errors + ' > ' + aux_errors;
                 exit;
                 exit;
@@ -4121,11 +4129,18 @@ begin
   end;
   end;
   // proof_of_work:
   // proof_of_work:
   {$IFnDEF TESTING_NO_POW_CHECK}
   {$IFnDEF TESTING_NO_POW_CHECK}
+  {$IFDEF ASSUME_VALID_POW_OLD_PROTOCOLS}
+  if (newOperationBlock.protocol_version>=CT_PROTOCOL_5) then begin
+  {$ENDIF}
   TPascalCoinProtocol.CalcProofOfWork(newOperationBlock,pow);
   TPascalCoinProtocol.CalcProofOfWork(newOperationBlock,pow);
   if (Not TBaseType.Equals(pow,newOperationBlock.proof_of_work)) then begin
   if (Not TBaseType.Equals(pow,newOperationBlock.proof_of_work)) then begin
     errors := 'Proof of work is bad calculated '+TCrypto.ToHexaString(newOperationBlock.proof_of_work)+' <> Good: '+TCrypto.ToHexaString(pow);
     errors := 'Proof of work is bad calculated '+TCrypto.ToHexaString(newOperationBlock.proof_of_work)+' <> Good: '+TCrypto.ToHexaString(pow);
     exit;
     exit;
   end;
   end;
+  {$IFDEF ASSUME_VALID_POW_OLD_PROTOCOLS}
+  end;
+  {$ENDIF}
+
   {$ENDIF}
   {$ENDIF}
   Result := true;
   Result := true;
 end;
 end;

+ 1 - 1
src/core/UConst.pas

@@ -195,7 +195,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.2'{$ELSE}{$IFDEF TESTNET}'TESTNET 5.2'{$ELSE}{$ENDIF}{$ENDIF};
+  CT_ClientAppVersion : String = {$IFDEF PRODUCTION}'5.3'{$ELSE}{$IFDEF TESTNET}'TESTNET 5.3'{$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};

+ 19 - 7
src/core/UNetProtocol.pas

@@ -509,7 +509,8 @@ implementation
 
 
 uses
 uses
   UConst, ULog, UNode, UTime, UPCEncryption, UChunk,
   UConst, ULog, UNode, UTime, UPCEncryption, UChunk,
-  UPCOperationsBlockValidator, UPCOperationsSignatureValidator;
+  UPCOperationsBlockValidator, UPCOperationsSignatureValidator,
+  UPCTemporalFileStream;
 
 
 Const
 Const
   CT_NetTransferType : Array[TNetTransferType] of String = ('Unknown','Request','Response','Autosend');
   CT_NetTransferType : Array[TNetTransferType] of String = ('Unknown','Request','Response','Autosend');
@@ -1855,8 +1856,10 @@ Const CT_LogSender = 'GetNewBlockChainFromClient';
     safeBoxHeader : TPCSafeBoxHeader;
     safeBoxHeader : TPCSafeBoxHeader;
     errors : String;
     errors : String;
     i : Integer;
     i : Integer;
+    LFirstSafebox : Boolean;
   Begin
   Begin
     Result := False;
     Result := False;
+    LFirstSafebox := TNode.Node.Bank.SafeBox.BlocksCount = 0;
     safeboxStream.Size:=0;
     safeboxStream.Size:=0;
     safeboxStream.Position:=0;
     safeboxStream.Position:=0;
     // Will try to download penultimate saved safebox
     // Will try to download penultimate saved safebox
@@ -1876,7 +1879,8 @@ Const CT_LogSender = 'GetNewBlockChainFromClient';
       for i:=0 to ((_blockcount-1) DIV 10000) do begin // Bug v3.0.1 and minors
       for i:=0 to ((_blockcount-1) DIV 10000) do begin // Bug v3.0.1 and minors
         FNewBlockChainFromClientStatus := Format('Receiving new safebox with %d blocks (step %d/%d) from %s',
         FNewBlockChainFromClientStatus := Format('Receiving new safebox with %d blocks (step %d/%d) from %s',
           [_blockcount,i+1,((_blockcount-1) DIV 10000)+1,Connection.ClientRemoteAddr]);
           [_blockcount,i+1,((_blockcount-1) DIV 10000)+1,Connection.ClientRemoteAddr]);
-        receiveChunk := TMemoryStream.Create;
+        if LFirstSafebox then receiveChunk := TMemoryStream.Create
+        else receiveChunk := TPCTemporalFileStream.Create('CHUNK_'+IntToStr(i)+'_');
         if (Not DownloadSafeBoxChunk(_blockcount,safebox_last_operation_block.initial_safe_box_hash,(i*10000),((i+1)*10000)-1,receiveChunk,safeBoxHeader,errors)) then begin
         if (Not DownloadSafeBoxChunk(_blockcount,safebox_last_operation_block.initial_safe_box_hash,(i*10000),((i+1)*10000)-1,receiveChunk,safeBoxHeader,errors)) then begin
           receiveChunk.Free;
           receiveChunk.Free;
           TLog.NewLog(ltError,CT_LogSender,errors);
           TLog.NewLog(ltError,CT_LogSender,errors);
@@ -1886,8 +1890,9 @@ Const CT_LogSender = 'GetNewBlockChainFromClient';
         chunks[High(chunks)].safeBoxHeader := safeBoxHeader;
         chunks[High(chunks)].safeBoxHeader := safeBoxHeader;
         chunks[High(chunks)].chunkStream := receiveChunk;
         chunks[High(chunks)].chunkStream := receiveChunk;
       end;
       end;
+      TLog.NewLog(ltDebug,CT_LogSender,Format('Concatening %d chunks',[Length(chunks)]));
       // Will concat safeboxs:
       // Will concat safeboxs:
-      chunk1 := TMemoryStream.Create;
+      chunk1 := TPCTemporalFileStream.Create('CONCAT_CHUNKS_');
       try
       try
         if (length(chunks)=1) then begin
         if (length(chunks)=1) then begin
           safeboxStream.CopyFrom(chunks[0].chunkStream,0);
           safeboxStream.CopyFrom(chunks[0].chunkStream,0);
@@ -1895,7 +1900,11 @@ Const CT_LogSender = 'GetNewBlockChainFromClient';
           chunk1.CopyFrom(chunks[0].chunkStream,0);
           chunk1.CopyFrom(chunks[0].chunkStream,0);
         end;
         end;
         for i:=1 to high(chunks) do begin
         for i:=1 to high(chunks) do begin
+          FNewBlockChainFromClientStatus := Format('Concatening downloaded safebox (step %d/%d) from %s',
+            [i,High(chunks),Connection.ClientRemoteAddr]);
+          TLog.NewLog(ltDebug,CT_LogSender,Format('Concatening chunk %d/%d',[i,High(chunks)]));
           safeboxStream.Size:=0;
           safeboxStream.Size:=0;
+          safeboxStream.Position := 0; // Added caused by FPC 3.0.4 bug that does not update position auto when setting size=0 at a TFileStream
           chunk1.Position:=0;
           chunk1.Position:=0;
           chunks[i].chunkStream.Position:=0;
           chunks[i].chunkStream.Position:=0;
           If Not TPCSafeBox.ConcatSafeBoxStream(chunk1,chunks[i].chunkStream,safeboxStream,errors) then begin
           If Not TPCSafeBox.ConcatSafeBoxStream(chunk1,chunks[i].chunkStream,safeboxStream,errors) then begin
@@ -1905,6 +1914,7 @@ Const CT_LogSender = 'GetNewBlockChainFromClient';
           chunk1.Size := 0;
           chunk1.Size := 0;
           chunk1.CopyFrom(safeboxStream,0);
           chunk1.CopyFrom(safeboxStream,0);
         end;
         end;
+        FNewBlockChainFromClientStatus := Format('Downloaded safebox with %d chunks from %s',[High(chunks),Connection.ClientRemoteAddr]);
       finally
       finally
         chunk1.Free;
         chunk1.Free;
       end;
       end;
@@ -1924,7 +1934,7 @@ Const CT_LogSender = 'GetNewBlockChainFromClient';
     request_id : Cardinal;
     request_id : Cardinal;
   Begin
   Begin
     Result := False;
     Result := False;
-    receiveData := TMemoryStream.Create;
+    receiveData := TPCTemporalFileStream.Create('SAFEBOX_');
     try
     try
       if Not DownloadSafeboxStream(receiveData,op) then Exit;
       if Not DownloadSafeboxStream(receiveData,op) then Exit;
       // Now receiveData is the ALL safebox
       // Now receiveData is the ALL safebox
@@ -1953,7 +1963,7 @@ Const CT_LogSender = 'GetNewBlockChainFromClient';
   end;
   end;
 
 
   procedure DownloadNewBlockchain(start_block : Int64; IsMyBlockChainOk : Boolean);
   procedure DownloadNewBlockchain(start_block : Int64; IsMyBlockChainOk : Boolean);
-  var safeboxStream : TMemoryStream;
+  var safeboxStream : TStream;
     newTmpBank : TPCBank;
     newTmpBank : TPCBank;
     safebox_last_operation_block : TOperationBlock;
     safebox_last_operation_block : TOperationBlock;
     opComp : TPCOperationsComp;
     opComp : TPCOperationsComp;
@@ -1971,7 +1981,7 @@ Const CT_LogSender = 'GetNewBlockChainFromClient';
     if (download_new_safebox) then begin
     if (download_new_safebox) then begin
       TLog.NewLog(ltinfo,ClassName,Format('Will download new safebox. My blocks:%d Remote blocks:%d Equal Block:%d (MaxFutureBlocksToDownloadNewSafebox:%d)',[TNode.Node.Bank.BlocksCount,Connection.RemoteOperationBlock.block+1,start_block-1,MinFutureBlocksToDownloadNewSafebox]));
       TLog.NewLog(ltinfo,ClassName,Format('Will download new safebox. My blocks:%d Remote blocks:%d Equal Block:%d (MaxFutureBlocksToDownloadNewSafebox:%d)',[TNode.Node.Bank.BlocksCount,Connection.RemoteOperationBlock.block+1,start_block-1,MinFutureBlocksToDownloadNewSafebox]));
       // Will try to download safebox
       // Will try to download safebox
-      safeboxStream := TMemoryStream.Create;
+      safeboxStream := TPCTemporalFileStream.Create('NEW_SAFEBOX_');
       Try
       Try
         if Not DownloadSafeboxStream(safeboxStream,safebox_last_operation_block) then Exit;
         if Not DownloadSafeboxStream(safeboxStream,safebox_last_operation_block) then Exit;
         safeboxStream.Position := 0;
         safeboxStream.Position := 0;
@@ -2046,6 +2056,7 @@ Const CT_LogSender = 'GetNewBlockChainFromClient';
 var rid : Cardinal;
 var rid : Cardinal;
   my_op, client_op : TOperationBlock;
   my_op, client_op : TOperationBlock;
   errors : String;
   errors : String;
+  LTickCount : TTickCount;
 begin
 begin
   // Protection against discovering servers...
   // Protection against discovering servers...
   if FIsDiscoveringServers then begin
   if FIsDiscoveringServers then begin
@@ -2056,6 +2067,7 @@ begin
 
 
   if (Not Assigned(TNode.Node.Bank.StorageClass)) then Exit;
   if (Not Assigned(TNode.Node.Bank.StorageClass)) then Exit;
   //
   //
+  LTickCount := TPlatform.GetTickCount;
   if Not FLockGettingNewBlockChainFromClient.TryEnter then begin
   if Not FLockGettingNewBlockChainFromClient.TryEnter then begin
     TLog.NewLog(ltdebug,CT_LogSender,'Is getting new blockchain from client...');
     TLog.NewLog(ltdebug,CT_LogSender,'Is getting new blockchain from client...');
     exit;
     exit;
@@ -2116,8 +2128,8 @@ begin
       DownloadNewBlockchain(my_op.block+1,True);
       DownloadNewBlockchain(my_op.block+1,True);
     end;
     end;
   Finally
   Finally
-    TLog.NewLog(ltdebug,CT_LogSender,'Finalizing');
     FLockGettingNewBlockChainFromClient.Release;
     FLockGettingNewBlockChainFromClient.Release;
+    TLog.NewLog(ltdebug,CT_LogSender,Format('Finalizing process in %d milis',[TPlatform.GetElapsedMilliseconds(LTickCount)]));
   end;
   end;
 end;
 end;
 
 

+ 81 - 0
src/core/UPCTemporalFileStream.pas

@@ -0,0 +1,81 @@
+unit UPCTemporalFileStream;
+
+{ Copyright (c) 2020 by Albert Molina
+
+  Distributed under the MIT software license, see the accompanying file LICENSE
+  or visit http://www.opensource.org/licenses/mit-license.php.
+
+  This unit is a part of the PascalCoin Project, an infinitely scalable
+  cryptocurrency. Find us here:
+  Web: https://www.pascalcoin.org
+  Source: https://github.com/PascalCoin/PascalCoin
+
+  If you like it, consider a donation using Bitcoin:
+  16K3HCZRhFUtM8GdWRcfKeaa6KsuyxZaYk
+
+  THIS LICENSE HEADER MUST NOT BE REMOVED.
+}
+
+{$IFDEF FPC}
+  {$MODE Delphi}
+{$ENDIF}
+
+interface
+
+uses
+  Classes, {$IFnDEF FPC}Windows,{$ENDIF} SysUtils;
+{$I ./../config.inc}
+
+Type
+  { TPCTemporalFileStream }
+
+  TPCTemporalFileStream = Class(TFileStream)
+  private
+    FTemporalFileName : String;
+  protected
+  public
+    Constructor Create(const AInitialName : String); reintroduce;
+    Destructor Destroy; override;
+  End;
+
+implementation
+
+Uses ULog, UNode;
+
+{ TPCTemporalFileStream }
+
+constructor TPCTemporalFileStream.Create(const AInitialName : String);
+var LFolder, LTime, LFileName : String;
+  i : Integer;
+begin
+  FTemporalFileName:= '';
+  LFolder := TNode.GetPascalCoinDataFolder+PathDelim+'Temp';
+  ForceDirectories(LFolder);
+  i := 0;
+  repeat
+    LTime := FormatDateTime('yyyymmddhhnnsszzz',Now);
+    if i>0 then begin
+      Sleep(1);
+      LFileName := LFolder + PathDelim + AInitialName + LTime +'_'+ IntToStr(i) + '.tmp';
+    end else begin
+      LFileName := LFolder + PathDelim + AInitialName + LTime + '.tmp';
+    end;
+    inc(i);
+  until (Not (FileExists(LFileName)) or (i>5000));
+  TLog.NewLog(ltdebug,ClassName,Format('Creating a new Temporal file Stream: %s',[LFileName]));
+  inherited Create(LFileName,fmCreate+fmShareDenyWrite);
+  FTemporalFileName:=LFileName;
+end;
+
+destructor TPCTemporalFileStream.Destroy;
+var LSize : Integer;
+begin
+  LSize := Size;
+  inherited Destroy;
+  if FTemporalFileName<>'' then begin
+    TLog.NewLog(ltdebug,ClassName,Format('Deleting a Temporal file Stream (%d bytes): %s',[LSize, FTemporalFileName]));
+    DeleteFile(FTemporalFileName);
+  end;
+end;
+
+end.

+ 16 - 9
src/gui-classic/UGridUtils.pas

@@ -97,7 +97,7 @@ Type
     procedure SetNode(const Value: TNode);
     procedure SetNode(const Value: TNode);
     function GetNode: TNode;
     function GetNode: TNode;
     procedure SetAllowMultiSelect(const Value: Boolean);
     procedure SetAllowMultiSelect(const Value: Boolean);
-    procedure TerminateAccountGridUpdateThread;
+    procedure TerminateAccountGridUpdateThread(AWaitUntilTerminated : Boolean);
     procedure SetAccountsGridFilter(const Value: TAccountsGridFilter);
     procedure SetAccountsGridFilter(const Value: TAccountsGridFilter);
     function GetAccountsCount: Integer;
     function GetAccountsCount: Integer;
     procedure SetAccountsGridDatasource(const Value: TAccountsGridDatasource);
     procedure SetAccountsGridDatasource(const Value: TAccountsGridDatasource);
@@ -343,8 +343,9 @@ begin
       end;
       end;
   Finally
   Finally
     FisProcessing := False;
     FisProcessing := False;
-    if Not Terminated then
+    if Not Terminated then begin
       Synchronize(SynchronizedOnTerminated);
       Synchronize(SynchronizedOnTerminated);
+    end;
   End;
   End;
 end;
 end;
 
 
@@ -447,7 +448,7 @@ end;
 
 
 destructor TAccountsGrid.Destroy;
 destructor TAccountsGrid.Destroy;
 begin
 begin
-  TerminateAccountGridUpdateThread;
+  TerminateAccountGridUpdateThread(True);
   FNodeNotifyEvents.Free;
   FNodeNotifyEvents.Free;
   FAccountsList.Free;
   FAccountsList.Free;
   inherited;
   inherited;
@@ -853,12 +854,18 @@ begin
   UpdateData;
   UpdateData;
 end;
 end;
 
 
-procedure TAccountsGrid.TerminateAccountGridUpdateThread;
+procedure TAccountsGrid.TerminateAccountGridUpdateThread(AWaitUntilTerminated : Boolean);
+var LTmp : TAccountsGridUpdateThread;
 begin
 begin
-  if Assigned(FAccountsGridUpdateThread) then begin
-    FAccountsGridUpdateThread.Terminate;
-    FAccountsGridUpdateThread.WaitFor;
-    FreeAndNil(FAccountsGridUpdateThread);
+  LTmp := FAccountsGridUpdateThread;
+  FAccountsGridUpdateThread := Nil;
+  if Assigned(Ltmp) then begin
+    if Not AWaitUntilTerminated then LTmp.FreeOnTerminate := True;
+    LTmp.Terminate;
+    if AWaitUntilTerminated then begin
+      LTmp.WaitFor;
+      FreeAndNil(LTmp);
+    end;
   end;
   end;
 end;
 end;
 
 
@@ -892,7 +899,7 @@ begin
   if Assigned(Node) then begin
   if Assigned(Node) then begin
     case FAccountsGridDatasource of
     case FAccountsGridDatasource of
       acds_NodeFiltered: begin
       acds_NodeFiltered: begin
-        TerminateAccountGridUpdateThread;
+        TerminateAccountGridUpdateThread(False);
         FAccountsBalance := 0;
         FAccountsBalance := 0;
         FAccountsGridUpdateThread := TAccountsGridUpdateThread.Create(Self,AccountsGridFilter);
         FAccountsGridUpdateThread := TAccountsGridUpdateThread.Create(Self,AccountsGridFilter);
       end;
       end;