Browse Source

TList to TList<T> - Core

In order to allow Delphi ARC architecture, TList is deprecated and will use TList<T>
PascalCoin 6 years ago
parent
commit
4c6ec0fb45

+ 12 - 11
src/core/UAccountKeyStorage.pas

@@ -7,7 +7,8 @@ unit UAccountKeyStorage;
 interface
 interface
 
 
 uses
 uses
-  Classes, SysUtils, UAccounts, UThread, UBaseTypes;
+  Classes, SysUtils, UAccounts, UThread, UBaseTypes,
+  {$IFNDEF FPC}System.Generics.Collections{$ELSE}Generics.Collections{$ENDIF};
 
 
 type
 type
   TAccountKeyStorageData = record
   TAccountKeyStorageData = record
@@ -22,8 +23,8 @@ type
   // Based on tests, allows a 10-20% memory reduction when multiple accounts use the same Account key
   // Based on tests, allows a 10-20% memory reduction when multiple accounts use the same Account key
   TAccountKeyStorage = Class
   TAccountKeyStorage = Class
   private
   private
-    FAccountKeys : TPCThreadList;
-    Function Find(list : TList; const accountKey: TAccountKey; var Index: Integer): Boolean;
+    FAccountKeys : TPCThreadList<Pointer>;
+    Function Find(list : TList<Pointer>; const accountKey: TAccountKey; out Index: Integer): Boolean;
   public
   public
     constructor Create;
     constructor Create;
     destructor Destroy; override;
     destructor Destroy; override;
@@ -31,7 +32,7 @@ type
     function AddAccountKeyExt(Const accountKey: TAccountKey) : PAccountKeyStorageData;
     function AddAccountKeyExt(Const accountKey: TAccountKey) : PAccountKeyStorageData;
     procedure RemoveAccountKey(Const accountKey: TAccountKey);
     procedure RemoveAccountKey(Const accountKey: TAccountKey);
     class function KS : TAccountKeyStorage;
     class function KS : TAccountKeyStorage;
-    function LockList : TList;
+    function LockList : TList<Pointer>;
     procedure UnlockList;
     procedure UnlockList;
   end;
   end;
 
 
@@ -44,7 +45,7 @@ var _aks : TAccountKeyStorage = Nil;
 
 
 { TAccountKeyStorage }
 { TAccountKeyStorage }
 
 
-function TAccountKeyStorage.Find(list : TList; const accountKey: TAccountKey; var Index: Integer): Boolean;
+function TAccountKeyStorage.Find(list : TList<Pointer>; const accountKey: TAccountKey; out Index: Integer): Boolean;
 var L, H, I: Integer;
 var L, H, I: Integer;
   C : Integer;
   C : Integer;
 begin
 begin
@@ -76,11 +77,11 @@ end;
 
 
 constructor TAccountKeyStorage.Create;
 constructor TAccountKeyStorage.Create;
 begin
 begin
-  FAccountKeys := TPCThreadList.Create('TAccountKeyStorage');
+  FAccountKeys := TPCThreadList<Pointer>.Create('TAccountKeyStorage');
 end;
 end;
 
 
 destructor TAccountKeyStorage.Destroy;
 destructor TAccountKeyStorage.Destroy;
-Var l : TList;
+Var l : TList<Pointer>;
   i : Integer;
   i : Integer;
   P1 : PAccountKeyStorageData;
   P1 : PAccountKeyStorageData;
   P2 : PAccountKey;
   P2 : PAccountKey;
@@ -102,7 +103,7 @@ begin
 end;
 end;
 
 
 function TAccountKeyStorage.AddAccountKey(const accountKey: TAccountKey): PAccountKey;
 function TAccountKeyStorage.AddAccountKey(const accountKey: TAccountKey): PAccountKey;
-var l : TList;
+var l : TList<Pointer>;
   i : Integer;
   i : Integer;
   P : PAccountKeyStorageData;
   P : PAccountKeyStorageData;
 begin
 begin
@@ -127,7 +128,7 @@ end;
 
 
 function TAccountKeyStorage.AddAccountKeyExt(const accountKey: TAccountKey): PAccountKeyStorageData;
 function TAccountKeyStorage.AddAccountKeyExt(const accountKey: TAccountKey): PAccountKeyStorageData;
   // This function will return allocated pointer and will increase counter like AddAccountKey
   // This function will return allocated pointer and will increase counter like AddAccountKey
-var l : TList;
+var l : TList<Pointer>;
   i : Integer;
   i : Integer;
 begin
 begin
   Result := Nil;
   Result := Nil;
@@ -149,7 +150,7 @@ begin
 end;
 end;
 
 
 procedure TAccountKeyStorage.RemoveAccountKey(const accountKey: TAccountKey);
 procedure TAccountKeyStorage.RemoveAccountKey(const accountKey: TAccountKey);
-var l : TList;
+var l : TList<Pointer>;
   i : Integer;
   i : Integer;
   P : PAccountKeyStorageData;
   P : PAccountKeyStorageData;
 begin
 begin
@@ -177,7 +178,7 @@ begin
   Result := _aks;
   Result := _aks;
 end;
 end;
 
 
-function TAccountKeyStorage.LockList: TList;
+function TAccountKeyStorage.LockList: TList<Pointer>;
 begin
 begin
   Result := FAccountKeys.LockList;
   Result := FAccountKeys.LockList;
 end;
 end;

+ 44 - 41
src/core/UAccounts.pas

@@ -24,7 +24,8 @@ interface
 
 
 uses
 uses
   Classes, SysUtils, UConst, UCrypto, SyncObjs, UThread, UBaseTypes,
   Classes, SysUtils, UConst, UCrypto, SyncObjs, UThread, UBaseTypes,
-  UPCOrderedLists, UPCDataTypes;
+  UPCOrderedLists, UPCDataTypes,
+  {$IFNDEF FPC}System.Generics.Collections{$ELSE}Generics.Collections{$ENDIF};
 
 
 {$I config.inc}
 {$I config.inc}
 
 
@@ -183,9 +184,9 @@ Type
   Private
   Private
     FAutoAddAll : Boolean;
     FAutoAddAll : Boolean;
     FAccountList : TPCSafeBox;
     FAccountList : TPCSafeBox;
-    FOrderedAccountKeysList : TPCThreadList; // An ordered list of pointers to quickly find account keys in account list
+    FOrderedAccountKeysList : TPCThreadList<Pointer>; // An ordered list of pointers to quickly find account keys in account list
     FTotalChanges : Integer;
     FTotalChanges : Integer;
-    Function Find(lockedList : TList; Const AccountKey: TAccountKey; var Index: Integer): Boolean;
+    Function Find(lockedList : TList<Pointer>; Const AccountKey: TAccountKey; var Index: Integer): Boolean;
     function GetAccountKeyChanges(index : Integer): Integer;
     function GetAccountKeyChanges(index : Integer): Integer;
     function GetAccountKeyList(index: Integer): TOrderedCardinalList;
     function GetAccountKeyList(index: Integer): TOrderedCardinalList;
     function GetAccountKey(index: Integer): TAccountKey;
     function GetAccountKey(index: Integer): TAccountKey;
@@ -208,7 +209,7 @@ Type
     Property SafeBox : TPCSafeBox read FAccountList;
     Property SafeBox : TPCSafeBox read FAccountList;
     Procedure Clear;
     Procedure Clear;
     function ToArray : TAccountKeyArray;
     function ToArray : TAccountKeyArray;
-    function Lock : TList;
+    function Lock : TList<Pointer>;
     procedure Unlock;
     procedure Unlock;
     function HasAccountKeyChanged : Boolean;
     function HasAccountKeyChanged : Boolean;
     procedure CopyFrom(const source : TOrderedAccountKeysList);
     procedure CopyFrom(const source : TOrderedAccountKeysList);
@@ -244,13 +245,13 @@ Type
 
 
   TPCSafeBox = Class
   TPCSafeBox = Class
   private
   private
-    FBlockAccountsList : TList; // Used when has no PreviousSafebox
+    FBlockAccountsList : TList<Pointer>; // Used when has no PreviousSafebox
     FModifiedBlocksSeparatedChain : TOrderedBlockAccountList; // Used when has PreviousSafebox (Used if we are on a Separated chain)
     FModifiedBlocksSeparatedChain : TOrderedBlockAccountList; // Used when has PreviousSafebox (Used if we are on a Separated chain)
     //
     //
     // OrderedAccountKeysList (Added after Build 3.0.1) allows an indexed search of public keys in the safebox with mem optimization
     // OrderedAccountKeysList (Added after Build 3.0.1) allows an indexed search of public keys in the safebox with mem optimization
     FOrderedAccountKeysList : TOrderedAccountKeysList;
     FOrderedAccountKeysList : TOrderedAccountKeysList;
     //
     //
-    FListOfOrderedAccountKeysList : TList;
+    FListOfOrderedAccountKeysList : TList<TOrderedAccountKeysList>;
     FBufferBlocksHash: TBytesBuffer;
     FBufferBlocksHash: TBytesBuffer;
     FOrderedByName : TOrderedRawList;
     FOrderedByName : TOrderedRawList;
     FTotalBalance: Int64;
     FTotalBalance: Int64;
@@ -259,7 +260,7 @@ Type
     FWorkSum : UInt64;
     FWorkSum : UInt64;
     FCurrentProtocol: Integer;
     FCurrentProtocol: Integer;
     // Snapshots utility new on V3
     // Snapshots utility new on V3
-    FSnapshots : TList; // Will save a Snapshots lists in order to rollback Safebox to a previous block state
+    FSnapshots : TList<Pointer>; // Will save a Snapshots lists in order to rollback Safebox to a previous block state
     FMaxSafeboxSnapshots : Integer;
     FMaxSafeboxSnapshots : Integer;
     // To be added to next snapshot
     // To be added to next snapshot
     FModifiedBlocksPreviousState : TOrderedBlockAccountList;
     FModifiedBlocksPreviousState : TOrderedBlockAccountList;
@@ -270,7 +271,7 @@ Type
     FPreviousSafeBox : TPCSafeBox;  // PreviousSafebox is the Safebox with snpashots where this safebox searches
     FPreviousSafeBox : TPCSafeBox;  // PreviousSafebox is the Safebox with snpashots where this safebox searches
     FPreviousSafeboxOriginBlock : Integer;
     FPreviousSafeboxOriginBlock : Integer;
     // Has chains based on this Safebox?
     // Has chains based on this Safebox?
-    FSubChains : TList; // Will link to subchains (other safebox) based on a current snapshot of this safebox
+    FSubChains : TList<TPCSafeBox>; // Will link to subchains (other safebox) based on a current snapshot of this safebox
     //
     //
     Procedure AccountKeyListAddAccounts(Const AccountKey : TAccountKey; const accounts : Array of Cardinal);
     Procedure AccountKeyListAddAccounts(Const AccountKey : TAccountKey; const accounts : Array of Cardinal);
     Procedure AccountKeyListRemoveAccount(Const AccountKey : TAccountKey; const accounts : Array of Cardinal);
     Procedure AccountKeyListRemoveAccount(Const AccountKey : TAccountKey; const accounts : Array of Cardinal);
@@ -340,7 +341,7 @@ Type
   TOrderedBlockAccountList = Class
   TOrderedBlockAccountList = Class
   private
   private
     FMaxBlockNumber : Integer;
     FMaxBlockNumber : Integer;
-    FList : TList;
+    FList : TList<Pointer>;
     Function Find(const block_number: Cardinal; out Index: Integer): Boolean;
     Function Find(const block_number: Cardinal; out Index: Integer): Boolean;
     Function SaveBlockAccount(Const blockAccount : TBlockAccount; UpdateIfFound : Boolean) : Integer;
     Function SaveBlockAccount(Const blockAccount : TBlockAccount; UpdateIfFound : Boolean) : Integer;
   public
   public
@@ -356,7 +357,7 @@ Type
 
 
   TOrderedAccountList = Class
   TOrderedAccountList = Class
   private
   private
-    FList : TList;
+    FList : TList<Pointer>;
     Function Find(const account_number: Cardinal; var Index: Integer): Boolean;
     Function Find(const account_number: Cardinal; var Index: Integer): Boolean;
   public
   public
     Constructor Create;
     Constructor Create;
@@ -377,7 +378,7 @@ Type
 
 
   TAccountPreviousBlockInfo = Class
   TAccountPreviousBlockInfo = Class
   private
   private
-    FList : TList;
+    FList : TList<Pointer>;
     Function FindAccount(const account: Cardinal; var Index: Integer): Boolean;
     Function FindAccount(const account: Cardinal; var Index: Integer): Boolean;
     function GetData(index : Integer): TAccountPreviousBlockInfoData;
     function GetData(index : Integer): TAccountPreviousBlockInfoData;
   public
   public
@@ -452,12 +453,12 @@ Type
 
 
 Const
 Const
   CT_OperationBlock_NUL : TOperationBlock = (block:0;account_key:(EC_OpenSSL_NID:0;x:Nil;y:Nil);reward:0;fee:0;protocol_version:0;
   CT_OperationBlock_NUL : TOperationBlock = (block:0;account_key:(EC_OpenSSL_NID:0;x:Nil;y:Nil);reward:0;fee:0;protocol_version:0;
-    protocol_available:0;timestamp:0;compact_target:0;nonce:0;block_payload:Nil;operations_hash:Nil;proof_of_work:Nil);
+    protocol_available:0;timestamp:0;compact_target:0;nonce:0;block_payload:Nil;initial_safe_box_hash:Nil;operations_hash:Nil;proof_of_work:Nil);
   CT_AccountInfo_NUL : TAccountInfo = (state:as_Unknown;accountKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil);locked_until_block:0;price:0;account_to_pay:0;new_publicKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil));
   CT_AccountInfo_NUL : TAccountInfo = (state:as_Unknown;accountKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil);locked_until_block:0;price:0;account_to_pay:0;new_publicKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil));
   CT_Account_NUL : TAccount = (account:0;accountInfo:(state:as_Unknown;accountKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil);locked_until_block:0;price:0;account_to_pay:0;new_publicKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil));balance:0;updated_block:0;n_operation:0;name:Nil;account_type:0;previous_updated_block:0);
   CT_Account_NUL : TAccount = (account:0;accountInfo:(state:as_Unknown;accountKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil);locked_until_block:0;price:0;account_to_pay:0;new_publicKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil));balance:0;updated_block:0;n_operation:0;name:Nil;account_type:0;previous_updated_block:0);
   CT_BlockAccount_NUL : TBlockAccount = (
   CT_BlockAccount_NUL : TBlockAccount = (
     blockchainInfo:(block:0;account_key:(EC_OpenSSL_NID:0;x:Nil;y:Nil);reward:0;fee:0;protocol_version:0;
     blockchainInfo:(block:0;account_key:(EC_OpenSSL_NID:0;x:Nil;y:Nil);reward:0;fee:0;protocol_version:0;
-    protocol_available:0;timestamp:0;compact_target:0;nonce:0;block_payload:Nil;operations_hash:Nil;proof_of_work:Nil);
+    protocol_available:0;timestamp:0;compact_target:0;nonce:0;block_payload:Nil;initial_safe_box_hash:Nil;operations_hash:Nil;proof_of_work:Nil);
     accounts:(
     accounts:(
     (account:0;accountInfo:(state:as_Unknown;accountKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil);locked_until_block:0;price:0;account_to_pay:0;new_publicKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil));balance:0;updated_block:0;n_operation:0;name:Nil;account_type:0;previous_updated_block:0),
     (account:0;accountInfo:(state:as_Unknown;accountKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil);locked_until_block:0;price:0;account_to_pay:0;new_publicKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil));balance:0;updated_block:0;n_operation:0;name:Nil;account_type:0;previous_updated_block:0),
     (account:0;accountInfo:(state:as_Unknown;accountKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil);locked_until_block:0;price:0;account_to_pay:0;new_publicKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil));balance:0;updated_block:0;n_operation:0;name:Nil;account_type:0;previous_updated_block:0),
     (account:0;accountInfo:(state:as_Unknown;accountKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil);locked_until_block:0;price:0;account_to_pay:0;new_publicKey:(EC_OpenSSL_NID:0;x:Nil;y:Nil));balance:0;updated_block:0;n_operation:0;name:Nil;account_type:0;previous_updated_block:0),
@@ -1079,7 +1080,6 @@ end;
 class function TAccountComp.AccountPublicKeyExport(const account: TAccountKey): String;
 class function TAccountComp.AccountPublicKeyExport(const account: TAccountKey): String;
 Var raw : TRawBytes;
 Var raw : TRawBytes;
   BN, BNMod, BNDiv : TBigNum;
   BN, BNMod, BNDiv : TBigNum;
-  i : Integer;
 begin
 begin
   Result := '';
   Result := '';
   raw := AccountKey2RawString(account);
   raw := AccountKey2RawString(account);
@@ -1459,7 +1459,6 @@ end;
 class function TAccountComp.TxtToMoney(const moneytxt: String;
 class function TAccountComp.TxtToMoney(const moneytxt: String;
   var money: Int64): Boolean;
   var money: Int64): Boolean;
 Var s : String;
 Var s : String;
-  i : Integer;
 begin
 begin
   money := 0;
   money := 0;
   if Trim(moneytxt)='' then begin
   if Trim(moneytxt)='' then begin
@@ -2095,7 +2094,7 @@ procedure TPCSafeBox.CheckMemory;
 {$IFDEF FPC}
 {$IFDEF FPC}
 Var sb : TPCSafeBox;
 Var sb : TPCSafeBox;
   tc : TTickCount;
   tc : TTickCount;
-  auxSnapshotsList : TList;
+  auxSnapshotsList : TList<Pointer>;
   i : Integer;
   i : Integer;
 {$ENDIF}
 {$ENDIF}
 begin
 begin
@@ -2107,17 +2106,21 @@ begin
     sb := TPCSafeBox.Create;
     sb := TPCSafeBox.Create;
     try
     try
       //
       //
-      auxSnapshotsList := TList.Create;
+      auxSnapshotsList := TList<Pointer>.Create;
       Try
       Try
         // Save snapshots:
         // Save snapshots:
-        auxSnapshotsList.Assign(FSnapshots);
+        for i:=0 to FSnapshots.Count-1 do begin
+          auxSnapshotsList.Add(FSnapshots.Items[i]);
+        end;
         FSnapshots.Clear;
         FSnapshots.Clear;
         //
         //
         sb.CopyFrom(Self);
         sb.CopyFrom(Self);
         Self.Clear;
         Self.Clear;
         Self.CopyFrom(sb);
         Self.CopyFrom(sb);
         // Restore snapshots:
         // Restore snapshots:
-        FSnapshots.Assign(auxSnapshotsList);
+        for i:=0 to auxSnapshotsList.Count-1 do begin
+          FSnapshots.Add(auxSnapshotsList.Items[i]);
+        end;
         // Clear changes to do not fire key activity
         // Clear changes to do not fire key activity
         for i := 0 to FListOfOrderedAccountKeysList.count-1 do begin
         for i := 0 to FListOfOrderedAccountKeysList.count-1 do begin
           TOrderedAccountKeysList( FListOfOrderedAccountKeysList[i] ).ClearAccountKeyChanges;
           TOrderedAccountKeysList( FListOfOrderedAccountKeysList[i] ).ClearAccountKeyChanges;
@@ -2269,11 +2272,11 @@ constructor TPCSafeBox.Create;
 begin
 begin
   FMaxSafeboxSnapshots:=CT_DEFAULT_MaxSafeboxSnapshots;
   FMaxSafeboxSnapshots:=CT_DEFAULT_MaxSafeboxSnapshots;
   FLock := TPCCriticalSection.Create('TPCSafeBox_Lock');
   FLock := TPCCriticalSection.Create('TPCSafeBox_Lock');
-  FBlockAccountsList := TList.Create;
-  FListOfOrderedAccountKeysList := TList.Create;
+  FBlockAccountsList := TList<Pointer>.Create;
+  FListOfOrderedAccountKeysList := TList<TOrderedAccountKeysList>.Create;
   FCurrentProtocol := CT_PROTOCOL_1;
   FCurrentProtocol := CT_PROTOCOL_1;
   FOrderedByName := TOrderedRawList.Create;
   FOrderedByName := TOrderedRawList.Create;
-  FSnapshots := TList.Create;
+  FSnapshots := TList<Pointer>.Create;
   FPreviousSafeBox := Nil;
   FPreviousSafeBox := Nil;
   FPreviousSafeboxOriginBlock := -1;
   FPreviousSafeboxOriginBlock := -1;
   FModifiedBlocksSeparatedChain := TOrderedBlockAccountList.Create;
   FModifiedBlocksSeparatedChain := TOrderedBlockAccountList.Create;
@@ -2281,7 +2284,7 @@ begin
   FModifiedBlocksFinalState := TOrderedBlockAccountList.Create;
   FModifiedBlocksFinalState := TOrderedBlockAccountList.Create;
   FAddedNamesSincePreviousSafebox := TOrderedRawList.Create;
   FAddedNamesSincePreviousSafebox := TOrderedRawList.Create;
   FDeletedNamesSincePreviousSafebox := TOrderedRawList.Create;
   FDeletedNamesSincePreviousSafebox := TOrderedRawList.Create;
-  FSubChains := TList.Create;
+  FSubChains := TList<TPCSafeBox>.Create;
   FOrderedAccountKeysList := TOrderedAccountKeysList.Create(Nil,True);
   FOrderedAccountKeysList := TOrderedAccountKeysList.Create(Nil,True);
   FBufferBlocksHash := TBytesBuffer.Create(1000*32);
   FBufferBlocksHash := TBytesBuffer.Create(1000*32);
   Clear;
   Clear;
@@ -4416,7 +4419,7 @@ end;
 
 
 constructor TOrderedBlockAccountList.Create;
 constructor TOrderedBlockAccountList.Create;
 begin
 begin
-  FList := TList.Create;
+  FList := TList<Pointer>.Create;
   FMaxBlockNumber:=-1;
   FMaxBlockNumber:=-1;
 end;
 end;
 
 
@@ -4496,7 +4499,7 @@ end;
 
 
 constructor TOrderedAccountList.Create;
 constructor TOrderedAccountList.Create;
 begin
 begin
-  FList := TList.Create;
+  FList := TList<Pointer>.Create;
 end;
 end;
 
 
 destructor TOrderedAccountList.Destroy;
 destructor TOrderedAccountList.Destroy;
@@ -4563,7 +4566,7 @@ end;
 procedure TOrderedAccountKeysList.AddAccountKey(const AccountKey: TAccountKey);
 procedure TOrderedAccountKeysList.AddAccountKey(const AccountKey: TAccountKey);
 Var P : POrderedAccountKeyList;
 Var P : POrderedAccountKeyList;
   i,j : Integer;
   i,j : Integer;
-  lockedList, safeboxLockedList : TList;
+  lockedList, safeboxLockedList : TList<Pointer>;
 begin
 begin
   lockedList := Lock;
   lockedList := Lock;
   Try
   Try
@@ -4621,7 +4624,7 @@ end;
 procedure TOrderedAccountKeysList.AddAccounts(const AccountKey: TAccountKey; const accounts: array of Cardinal);
 procedure TOrderedAccountKeysList.AddAccounts(const AccountKey: TAccountKey; const accounts: array of Cardinal);
 Var P : POrderedAccountKeyList;
 Var P : POrderedAccountKeyList;
   i,i2 : Integer;
   i,i2 : Integer;
-  lockedList : TList;
+  lockedList : TList<Pointer>;
 begin
 begin
   lockedList := Lock;
   lockedList := Lock;
   Try
   Try
@@ -4671,7 +4674,7 @@ begin
   end;
   end;
 end;
 end;
 
 
-function TOrderedAccountKeysList.Lock: TList;
+function TOrderedAccountKeysList.Lock: TList<Pointer>;
 begin
 begin
   Result := FOrderedAccountKeysList.LockList;
   Result := FOrderedAccountKeysList.LockList;
 end;
 end;
@@ -4687,7 +4690,7 @@ begin
 end;
 end;
 
 
 procedure TOrderedAccountKeysList.CopyFrom(const source: TOrderedAccountKeysList);
 procedure TOrderedAccountKeysList.CopyFrom(const source: TOrderedAccountKeysList);
-var selfList,sourceList : TList;
+var selfList,sourceList : TList<Pointer>;
   i : Integer;
   i : Integer;
   newP,sourceP : POrderedAccountKeyList;
   newP,sourceP : POrderedAccountKeyList;
 begin
 begin
@@ -4723,7 +4726,7 @@ end;
 procedure TOrderedAccountKeysList.ClearAccounts(RemoveAccountList : Boolean);
 procedure TOrderedAccountKeysList.ClearAccounts(RemoveAccountList : Boolean);
 Var P : POrderedAccountKeyList;
 Var P : POrderedAccountKeyList;
   i : Integer;
   i : Integer;
-  lockedList : TList;
+  lockedList : TList<Pointer>;
 begin
 begin
   lockedList := Lock;
   lockedList := Lock;
   Try
   Try
@@ -4750,7 +4753,7 @@ begin
 end;
 end;
 
 
 function TOrderedAccountKeysList.Count: Integer;
 function TOrderedAccountKeysList.Count: Integer;
-var lockedList : TList;
+var lockedList : TList<Pointer>;
 begin
 begin
   lockedList := Lock;
   lockedList := Lock;
   Try
   Try
@@ -4767,7 +4770,7 @@ begin
   FAutoAddAll := AutoAddAll;
   FAutoAddAll := AutoAddAll;
   FAccountList := AccountList;
   FAccountList := AccountList;
   FTotalChanges:=0;
   FTotalChanges:=0;
-  FOrderedAccountKeysList := TPCThreadList.Create(ClassName);
+  FOrderedAccountKeysList := TPCThreadList<Pointer>.Create(ClassName);
   if Assigned(AccountList) then begin
   if Assigned(AccountList) then begin
     Lock;
     Lock;
     Try
     Try
@@ -4794,7 +4797,7 @@ begin
   inherited;
   inherited;
 end;
 end;
 
 
-function TOrderedAccountKeysList.Find(lockedList : TList; const AccountKey: TAccountKey; var Index: Integer): Boolean;
+function TOrderedAccountKeysList.Find(lockedList : TList<Pointer>; const AccountKey: TAccountKey; var Index: Integer): Boolean;
 var L, H, I: Integer;
 var L, H, I: Integer;
   C : Int64;
   C : Int64;
   {$IFDEF useAccountKeyStorage}
   {$IFDEF useAccountKeyStorage}
@@ -4836,7 +4839,7 @@ begin
 end;
 end;
 
 
 function TOrderedAccountKeysList.GetAccountKeyChanges(index : Integer): Integer;
 function TOrderedAccountKeysList.GetAccountKeyChanges(index : Integer): Integer;
-var lockedList : TList;
+var lockedList : TList<Pointer>;
 begin
 begin
   lockedList := Lock;
   lockedList := Lock;
   Try
   Try
@@ -4847,7 +4850,7 @@ begin
 end;
 end;
 
 
 function TOrderedAccountKeysList.GetAccountKey(index: Integer): TAccountKey;
 function TOrderedAccountKeysList.GetAccountKey(index: Integer): TAccountKey;
-Var lockedList : TList;
+Var lockedList : TList<Pointer>;
   {$IFDEF useAccountKeyStorage}
   {$IFDEF useAccountKeyStorage}
   {$ELSE}
   {$ELSE}
   raw : TRawBytes;
   raw : TRawBytes;
@@ -4867,7 +4870,7 @@ begin
 end;
 end;
 
 
 function TOrderedAccountKeysList.GetAccountKeyList(index: Integer): TOrderedCardinalList;
 function TOrderedAccountKeysList.GetAccountKeyList(index: Integer): TOrderedCardinalList;
-var lockedList : TList;
+var lockedList : TList<Pointer>;
 begin
 begin
   lockedList := Lock;
   lockedList := Lock;
   Try
   Try
@@ -4878,7 +4881,7 @@ begin
 end;
 end;
 
 
 function TOrderedAccountKeysList.IndexOfAccountKey(const AccountKey: TAccountKey): Integer;
 function TOrderedAccountKeysList.IndexOfAccountKey(const AccountKey: TAccountKey): Integer;
-var lockedList : TList;
+var lockedList : TList<Pointer>;
 begin
 begin
   lockedList := Lock;
   lockedList := Lock;
   Try
   Try
@@ -4890,7 +4893,7 @@ end;
 
 
 procedure TOrderedAccountKeysList.ClearAccountKeyChanges;
 procedure TOrderedAccountKeysList.ClearAccountKeyChanges;
 var i : Integer;
 var i : Integer;
-  lockedList : TList;
+  lockedList : TList<Pointer>;
 begin
 begin
   lockedList := Lock;
   lockedList := Lock;
   Try
   Try
@@ -4906,7 +4909,7 @@ end;
 procedure TOrderedAccountKeysList.RemoveAccounts(const AccountKey: TAccountKey; const accounts: array of Cardinal);
 procedure TOrderedAccountKeysList.RemoveAccounts(const AccountKey: TAccountKey; const accounts: array of Cardinal);
 Var P : POrderedAccountKeyList;
 Var P : POrderedAccountKeyList;
   i,j : Integer;
   i,j : Integer;
-  lockedList : TList;
+  lockedList : TList<Pointer>;
 begin
 begin
   lockedList := Lock;
   lockedList := Lock;
   Try
   Try
@@ -4935,7 +4938,7 @@ end;
 procedure TOrderedAccountKeysList.RemoveAccountKey(const AccountKey: TAccountKey);
 procedure TOrderedAccountKeysList.RemoveAccountKey(const AccountKey: TAccountKey);
 Var P : POrderedAccountKeyList;
 Var P : POrderedAccountKeyList;
   i,j : Integer;
   i,j : Integer;
-  lockedList : TList;
+  lockedList : TList<Pointer>;
 begin
 begin
   lockedList := Lock;
   lockedList := Lock;
   Try
   Try
@@ -4993,7 +4996,7 @@ end;
 
 
 constructor TAccountPreviousBlockInfo.Create;
 constructor TAccountPreviousBlockInfo.Create;
 begin
 begin
-  FList := TList.Create;
+  FList := TList<Pointer>.Create;
 end;
 end;
 
 
 destructor TAccountPreviousBlockInfo.Destroy;
 destructor TAccountPreviousBlockInfo.Destroy;

+ 78 - 76
src/core/UBlockChain.pas

@@ -24,6 +24,7 @@ interface
 
 
 uses
 uses
   Classes, UCrypto, UAccounts, ULog, UThread, SyncObjs, UBaseTypes, SysUtils,
   Classes, UCrypto, UAccounts, ULog, UThread, SyncObjs, UBaseTypes, SysUtils,
+  {$IFNDEF FPC}System.Generics.Collections{$ELSE}Generics.Collections{$ENDIF},
   UPCDataTypes;
   UPCDataTypes;
 {$I config.inc}
 {$I config.inc}
 
 
@@ -180,7 +181,7 @@ Type
 
 
   TOperationsResumeList = Class
   TOperationsResumeList = Class
   private
   private
-    FList : TPCThreadList;
+    FList : TPCThreadList<Pointer>;
     function GetOperationResume(index: Integer): TOperationResume;
     function GetOperationResume(index: Integer): TOperationResume;
   public
   public
     Constructor Create;
     Constructor Create;
@@ -220,7 +221,7 @@ Type
     destructor Destroy; override;
     destructor Destroy; override;
     function GetBufferForOpHash(UseProtocolV2 : Boolean): TRawBytes; virtual;
     function GetBufferForOpHash(UseProtocolV2 : Boolean): TRawBytes; virtual;
     function DoOperation(AccountPreviousUpdatedBlock : TAccountPreviousBlockInfo; AccountTransaction : TPCSafeBoxTransaction; var errors: String): Boolean; virtual; abstract;
     function DoOperation(AccountPreviousUpdatedBlock : TAccountPreviousBlockInfo; AccountTransaction : TPCSafeBoxTransaction; var errors: String): Boolean; virtual; abstract;
-    procedure AffectedAccounts(list : TList); virtual; abstract;
+    procedure AffectedAccounts(list : TList<Cardinal>); virtual; abstract;
     class function OpType: Byte; virtual; abstract;
     class function OpType: Byte; virtual; abstract;
     Class Function OperationToOperationResume(Block : Cardinal; Operation : TPCOperation; getInfoForAllAccounts : Boolean; Affected_account_number : Cardinal; var OperationResume : TOperationResume) : Boolean; virtual;
     Class Function OperationToOperationResume(Block : Cardinal; Operation : TPCOperation; getInfoForAllAccounts : Boolean; Affected_account_number : Cardinal; var OperationResume : TOperationResume) : Boolean; virtual;
     Function GetDigestToSign(current_protocol : Word) : TRawBytes; virtual; abstract;
     Function GetDigestToSign(current_protocol : Word) : TRawBytes; virtual; abstract;
@@ -229,7 +230,7 @@ Type
     function OperationFee: Int64; virtual; abstract;
     function OperationFee: Int64; virtual; abstract;
     function OperationPayload : TRawBytes; virtual; abstract;
     function OperationPayload : TRawBytes; virtual; abstract;
     function SignerAccount : Cardinal; virtual; abstract;
     function SignerAccount : Cardinal; virtual; abstract;
-    procedure SignerAccounts(list : TList); virtual;
+    procedure SignerAccounts(list : TList<Cardinal>); virtual;
     function IsSignerAccount(account : Cardinal) : Boolean; virtual;
     function IsSignerAccount(account : Cardinal) : Boolean; virtual;
     function IsAffectedAccount(account : Cardinal) : Boolean; virtual;
     function IsAffectedAccount(account : Cardinal) : Boolean; virtual;
     function DestinationAccount : Int64; virtual;
     function DestinationAccount : Int64; virtual;
@@ -277,14 +278,14 @@ Type
     FIntTotalDeleted : Integer;
     FIntTotalDeleted : Integer;
     FMaxLocksCount : Integer;
     FMaxLocksCount : Integer;
     FMaxLocksValue : Integer;
     FMaxLocksValue : Integer;
-    FPCOperationsStorageList : TPCThreadList; // Lock thread to POperationTStorage list
-    Function FindOrderedByPtrPCOperation(lockedThreadList : TList; const Value: TPCOperation; out Index: Integer): Boolean;
+    FPCOperationsStorageList : TPCThreadList<Pointer>; // Lock thread to POperationTStorage list
+    Function FindOrderedByPtrPCOperation(lockedThreadList : TList<Pointer>; const Value: TPCOperation; out Index: Integer): Boolean;
   protected
   protected
   public
   public
     Constructor Create;
     Constructor Create;
     Destructor Destroy; override;
     Destructor Destroy; override;
     //
     //
-    function LockPCOperationsStorage : TList;
+    function LockPCOperationsStorage : TList<Pointer>;
     procedure UnlockPCOperationsStorage;
     procedure UnlockPCOperationsStorage;
     Function Count : Integer;
     Function Count : Integer;
     procedure AddPCOperation(APCOperation : TPCOperation);
     procedure AddPCOperation(APCOperation : TPCOperation);
@@ -299,20 +300,20 @@ Type
 
 
   TOperationsHashTree = Class
   TOperationsHashTree = Class
   private
   private
-    FListOrderedByAccountsData : TList;
-    FListOrderedBySha256 : TList; // Improvement TOperationsHashTree speed 2.1.6
-    FListOrderedByOpReference : TList;
-    FHashTreeOperations : TPCThreadList; // Improvement TOperationsHashTree speed 2.1.6
+    FListOrderedByAccountsData : TList<Pointer>;
+    FListOrderedBySha256 : TList<Integer>; // Improvement TOperationsHashTree speed 2.1.6
+    FListOrderedByOpReference : TList<Integer>;
+    FHashTreeOperations : TPCThreadList<Pointer>; // Improvement TOperationsHashTree speed 2.1.6
     FHashTree: TRawBytes;
     FHashTree: TRawBytes;
     FOnChanged: TNotifyEvent;
     FOnChanged: TNotifyEvent;
     FTotalAmount : Int64;
     FTotalAmount : Int64;
     FTotalFee : Int64;
     FTotalFee : Int64;
     FMax0feeOperationsBySigner : Integer;
     FMax0feeOperationsBySigner : Integer;
-    function InternalCanAddOperationToHashTree(lockedThreadList : TList; op : TPCOperation) : Boolean;
-    function InternalAddOperationToHashTree(list : TList; op : TPCOperation; CalcNewHashTree : Boolean) : Boolean;
-    Function FindOrderedByOpReference(lockedThreadList : TList; const Value: TOpReference; var Index: Integer): Boolean;
-    Function FindOrderedBySha(lockedThreadList : TList; const Value: TRawBytes; var Index: Integer): Boolean;
-    Function FindOrderedByAccountData(lockedThreadList : TList; const account_number : Cardinal; var Index: Integer): Boolean;
+    function InternalCanAddOperationToHashTree(lockedThreadList : TList<Pointer>; op : TPCOperation) : Boolean;
+    function InternalAddOperationToHashTree(list : TList<Pointer>; op : TPCOperation; CalcNewHashTree : Boolean) : Boolean;
+    Function FindOrderedByOpReference(lockedThreadList : TList<Pointer>; const Value: TOpReference; var Index: Integer): Boolean;
+    Function FindOrderedBySha(lockedThreadList : TList<Pointer>; const Value: TRawBytes; var Index: Integer): Boolean;
+    Function FindOrderedByAccountData(lockedThreadList : TList<Pointer>; const account_number : Cardinal; var Index: Integer): Boolean;
     function GetHashTree: TRawBytes;
     function GetHashTree: TRawBytes;
     procedure SetMax0feeOperationsBySigner(const Value: Integer);
     procedure SetMax0feeOperationsBySigner(const Value: Integer);
   public
   public
@@ -324,7 +325,7 @@ Type
     Property HashTree : TRawBytes read GetHashTree;
     Property HashTree : TRawBytes read GetHashTree;
     Function OperationsCount : Integer;
     Function OperationsCount : Integer;
     Function GetOperation(index : Integer) : TPCOperation;
     Function GetOperation(index : Integer) : TPCOperation;
-    Function GetOperationsAffectingAccount(account_number : Cardinal; List : TList) : Integer;
+    Function GetOperationsAffectingAccount(account_number : Cardinal; List : TList<Cardinal>) : Integer;
     Procedure CopyFromHashTree(Sender : TOperationsHashTree);
     Procedure CopyFromHashTree(Sender : TOperationsHashTree);
     Property TotalAmount : Int64 read FTotalAmount;
     Property TotalAmount : Int64 read FTotalAmount;
     Property TotalFee : Int64 read FTotalFee;
     Property TotalFee : Int64 read FTotalFee;
@@ -505,7 +506,7 @@ Type
     FUpgradingToV2: Boolean;
     FUpgradingToV2: Boolean;
     FOnLog: TPCBankLog;
     FOnLog: TPCBankLog;
     FBankLock: TPCCriticalSection;
     FBankLock: TPCCriticalSection;
-    FNotifyList : TList;
+    FNotifyList : TList<TPCBankNotify>;
     FStorageClass: TStorageClass;
     FStorageClass: TStorageClass;
     function GetStorage: TStorage;
     function GetStorage: TStorage;
     procedure SetStorageClass(const Value: TStorageClass);
     procedure SetStorageClass(const Value: TStorageClass);
@@ -552,7 +553,7 @@ uses
 var
 var
    _PCOperationsStorage : TPCOperationsStorage;
    _PCOperationsStorage : TPCOperationsStorage;
 
 
-function TPCOperationsStorage.FindOrderedByPtrPCOperation(lockedThreadList: TList; const Value: TPCOperation; out Index: Integer): Boolean;
+function TPCOperationsStorage.FindOrderedByPtrPCOperation(lockedThreadList: TList<Pointer>; const Value: TPCOperation; out Index: Integer): Boolean;
 var L, H, I: Integer;
 var L, H, I: Integer;
   C : PtrInt;
   C : PtrInt;
 begin
 begin
@@ -578,7 +579,7 @@ end;
 
 
 constructor TPCOperationsStorage.Create;
 constructor TPCOperationsStorage.Create;
 begin
 begin
-  FPCOperationsStorageList := TPCThreadList.Create(ClassName);
+  FPCOperationsStorageList := TPCThreadList<Pointer>.Create(ClassName);
   FIntTotalNewOps := 0;
   FIntTotalNewOps := 0;
   FIntTotalAdded := 0;
   FIntTotalAdded := 0;
   FIntTotalDeleted := 0;
   FIntTotalDeleted := 0;
@@ -587,7 +588,7 @@ begin
 end;
 end;
 
 
 destructor TPCOperationsStorage.Destroy;
 destructor TPCOperationsStorage.Destroy;
-Var list : TList;
+Var list : TList<Pointer>;
   P : PPCOperationTStorage;
   P : PPCOperationTStorage;
   i : Integer;
   i : Integer;
   pc : TPCOperation;
   pc : TPCOperation;
@@ -611,7 +612,7 @@ begin
   inherited Destroy;
   inherited Destroy;
 end;
 end;
 
 
-function TPCOperationsStorage.LockPCOperationsStorage: TList;
+function TPCOperationsStorage.LockPCOperationsStorage: TList<Pointer>;
 begin
 begin
   Result := FPCOperationsStorageList.LockList;
   Result := FPCOperationsStorageList.LockList;
 end;
 end;
@@ -622,7 +623,7 @@ begin
 end;
 end;
 
 
 function TPCOperationsStorage.Count: Integer;
 function TPCOperationsStorage.Count: Integer;
-var list : TList;
+var list : TList<Pointer>;
 begin
 begin
   list := LockPCOperationsStorage;
   list := LockPCOperationsStorage;
   try
   try
@@ -634,7 +635,7 @@ end;
 
 
 procedure TPCOperationsStorage.AddPCOperation(APCOperation: TPCOperation);
 procedure TPCOperationsStorage.AddPCOperation(APCOperation: TPCOperation);
 var P : PPCOperationTStorage;
 var P : PPCOperationTStorage;
-  list : TList;
+  list : TList<Pointer>;
   iPos : Integer;
   iPos : Integer;
 begin
 begin
   list := LockPCOperationsStorage;
   list := LockPCOperationsStorage;
@@ -662,7 +663,7 @@ end;
 
 
 procedure TPCOperationsStorage.RemovePCOperation(APCOperation: TPCOperation);
 procedure TPCOperationsStorage.RemovePCOperation(APCOperation: TPCOperation);
 var P : PPCOperationTStorage;
 var P : PPCOperationTStorage;
-  list : TList;
+  list : TList<Pointer>;
   iPos : Integer;
   iPos : Integer;
 begin
 begin
   list := LockPCOperationsStorage;
   list := LockPCOperationsStorage;
@@ -687,7 +688,7 @@ begin
 end;
 end;
 
 
 function TPCOperationsStorage.FindPCOperation(APCOperation: TPCOperation): Boolean;
 function TPCOperationsStorage.FindPCOperation(APCOperation: TPCOperation): Boolean;
-var list : TList;
+var list : TList<Pointer>;
   iPos : Integer;
   iPos : Integer;
 begin
 begin
   list := LockPCOperationsStorage;
   list := LockPCOperationsStorage;
@@ -699,7 +700,7 @@ begin
 end;
 end;
 
 
 function TPCOperationsStorage.FindPCOperationAndIncCounterIfFound(APCOperation: TPCOperation): Boolean;
 function TPCOperationsStorage.FindPCOperationAndIncCounterIfFound(APCOperation: TPCOperation): Boolean;
-var list : TList;
+var list : TList<Pointer>;
   iPos : Integer;
   iPos : Integer;
 begin
 begin
   list := LockPCOperationsStorage;
   list := LockPCOperationsStorage;
@@ -725,7 +726,7 @@ begin
 end;
 end;
 
 
 procedure TPCOperationsStorage.GetStats(strings: TStrings);
 procedure TPCOperationsStorage.GetStats(strings: TStrings);
-var list : TList;
+var list : TList<Pointer>;
   i : Integer;
   i : Integer;
   P : PPCOperationTStorage;
   P : PPCOperationTStorage;
 begin
 begin
@@ -852,7 +853,7 @@ begin
   FIsRestoringFromFile := False;
   FIsRestoringFromFile := False;
   FOnLog := Nil;
   FOnLog := Nil;
   FSafeBox := TPCSafeBox.Create;
   FSafeBox := TPCSafeBox.Create;
-  FNotifyList := TList.Create;
+  FNotifyList := TList<TPCBankNotify>.Create;
   FLastBlockCache := TPCOperationsComp.Create(Nil);
   FLastBlockCache := TPCOperationsComp.Create(Nil);
   FIsRestoringFromFile:=False;
   FIsRestoringFromFile:=False;
   FUpgradingToV2:=False;
   FUpgradingToV2:=False;
@@ -2000,7 +2001,7 @@ Type TOperationHashTreeReg = Record
      POperationsHashAccountsData = ^TOperationsHashAccountsData;
      POperationsHashAccountsData = ^TOperationsHashAccountsData;
 
 
 function TOperationsHashTree.AddOperationToHashTree(op: TPCOperation) : Boolean;
 function TOperationsHashTree.AddOperationToHashTree(op: TPCOperation) : Boolean;
-Var l : TList;
+Var l : TList<Pointer>;
 begin
 begin
   l := FHashTreeOperations.LockList;
   l := FHashTreeOperations.LockList;
   try
   try
@@ -2011,7 +2012,7 @@ begin
 end;
 end;
 
 
 function TOperationsHashTree.CanAddOperationToHashTree(op: TPCOperation): Boolean;
 function TOperationsHashTree.CanAddOperationToHashTree(op: TPCOperation): Boolean;
-Var lockedList : TList;
+Var lockedList : TList<Pointer>;
 begin
 begin
   lockedList := FHashTreeOperations.LockList;
   lockedList := FHashTreeOperations.LockList;
   Try
   Try
@@ -2022,7 +2023,7 @@ begin
 end;
 end;
 
 
 procedure TOperationsHashTree.ClearHastThree;
 procedure TOperationsHashTree.ClearHastThree;
-var l : TList;
+var l : TList<Pointer>;
   i : Integer;
   i : Integer;
   P : POperationHashTreeReg;
   P : POperationHashTreeReg;
   PaccData : POperationsHashAccountsData;
   PaccData : POperationsHashAccountsData;
@@ -2056,7 +2057,7 @@ end;
 
 
 procedure TOperationsHashTree.CopyFromHashTree(Sender: TOperationsHashTree);
 procedure TOperationsHashTree.CopyFromHashTree(Sender: TOperationsHashTree);
 Var i : Integer;
 Var i : Integer;
-  lme, lsender : TList;
+  lme, lsender : TList<Pointer>;
   PSender : POperationHashTreeReg;
   PSender : POperationHashTreeReg;
   lastNE : TNotifyEvent;
   lastNE : TNotifyEvent;
 begin
 begin
@@ -2094,18 +2095,18 @@ end;
 constructor TOperationsHashTree.Create;
 constructor TOperationsHashTree.Create;
 begin
 begin
   FOnChanged:=Nil;
   FOnChanged:=Nil;
-  FListOrderedBySha256 := TList.Create;
-  FListOrderedByAccountsData := TList.Create;
-  FListOrderedByOpReference := TList.Create;
+  FListOrderedBySha256 := TList<Integer>.Create;
+  FListOrderedByAccountsData := TList<Pointer>.Create;
+  FListOrderedByOpReference := TList<Integer>.Create;
   FTotalAmount := 0;
   FTotalAmount := 0;
   FTotalFee := 0;
   FTotalFee := 0;
   FHashTree := Nil;
   FHashTree := Nil;
   FMax0feeOperationsBySigner := -1; // Unlimited by default
   FMax0feeOperationsBySigner := -1; // Unlimited by default
-  FHashTreeOperations := TPCThreadList.Create('TOperationsHashTree_HashTreeOperations');
+  FHashTreeOperations := TPCThreadList<Pointer>.Create('TOperationsHashTree_HashTreeOperations');
 end;
 end;
 
 
 procedure TOperationsHashTree.Delete(index: Integer);
 procedure TOperationsHashTree.Delete(index: Integer);
-Var l : TList;
+Var l : TList<Pointer>;
   P : POperationHashTreeReg;
   P : POperationHashTreeReg;
   i,iDel,iValuePosDeleted : Integer;
   i,iDel,iValuePosDeleted : Integer;
   PaccData : POperationsHashAccountsData;
   PaccData : POperationsHashAccountsData;
@@ -2127,7 +2128,7 @@ begin
     // Decrease FListOrderedByOpReference values > index
     // Decrease FListOrderedByOpReference values > index
     for i := 0 to FListOrderedByOpReference.Count - 1 do begin
     for i := 0 to FListOrderedByOpReference.Count - 1 do begin
       if PtrInt(FListOrderedByOpReference[i])>index then begin
       if PtrInt(FListOrderedByOpReference[i])>index then begin
-        FListOrderedByOpReference[i] := TObject( PtrInt(FListOrderedByOpReference[i]) - 1 );
+        FListOrderedByOpReference[i] := ( (FListOrderedByOpReference[i]) - 1 );
       end;
       end;
     end;
     end;
 
 
@@ -2144,7 +2145,7 @@ begin
     // Decrease FListOrderedBySha256 values > index
     // Decrease FListOrderedBySha256 values > index
     for i := 0 to FListOrderedBySha256.Count - 1 do begin
     for i := 0 to FListOrderedBySha256.Count - 1 do begin
       if PtrInt(FListOrderedBySha256[i])>index then begin
       if PtrInt(FListOrderedBySha256[i])>index then begin
-        FListOrderedBySha256[i] := TObject( PtrInt(FListOrderedBySha256[i]) - 1 );
+        FListOrderedBySha256[i] := ( (FListOrderedBySha256[i]) - 1 );
       end;
       end;
     end;
     end;
 
 
@@ -2193,7 +2194,7 @@ begin
 end;
 end;
 
 
 function TOperationsHashTree.GetHashTree: TRawBytes;
 function TOperationsHashTree.GetHashTree: TRawBytes;
-Var l : TList;
+Var l : TList<Pointer>;
   i : Integer;
   i : Integer;
   P : POperationHashTreeReg;
   P : POperationHashTreeReg;
   tmpRaw : TRawBytes;
   tmpRaw : TRawBytes;
@@ -2217,7 +2218,7 @@ begin
 end;
 end;
 
 
 function TOperationsHashTree.GetOperation(index: Integer): TPCOperation;
 function TOperationsHashTree.GetOperation(index: Integer): TPCOperation;
-Var l : TList;
+Var l : TList<Pointer>;
 begin
 begin
   l := FHashTreeOperations.LockList;
   l := FHashTreeOperations.LockList;
   try
   try
@@ -2227,20 +2228,21 @@ begin
   end;
   end;
 end;
 end;
 
 
-function TOperationsHashTree.GetOperationsAffectingAccount(account_number: Cardinal; List: TList): Integer;
+function TOperationsHashTree.GetOperationsAffectingAccount(account_number: Cardinal; List: TList<Cardinal>): Integer;
   // This function retrieves operations from HashTree that affeccts to an account_number
   // This function retrieves operations from HashTree that affeccts to an account_number
-Var l,intl : TList;
+Var l : TList<Pointer>;
+  intl : TList<Cardinal>;
   i,j : Integer;
   i,j : Integer;
 begin
 begin
   List.Clear;
   List.Clear;
   l := FHashTreeOperations.LockList;
   l := FHashTreeOperations.LockList;
   try
   try
-    intl := TList.Create;
+    intl := TList<Cardinal>.Create;
     try
     try
       for i := 0 to l.Count - 1 do begin
       for i := 0 to l.Count - 1 do begin
         intl.Clear;
         intl.Clear;
         POperationHashTreeReg(l[i])^.Op.AffectedAccounts(intl);
         POperationHashTreeReg(l[i])^.Op.AffectedAccounts(intl);
-        if intl.IndexOf(TObject(account_number))>=0 then List.Add(TObject(i));
+        if intl.IndexOf(account_number)>=0 then List.Add(Cardinal(i));
       end;
       end;
     finally
     finally
       intl.Free;
       intl.Free;
@@ -2253,7 +2255,7 @@ end;
 
 
 function TOperationsHashTree.IndexOfOperation(op: TPCOperation): Integer;
 function TOperationsHashTree.IndexOfOperation(op: TPCOperation): Integer;
 Var iPosInOrdered : Integer;
 Var iPosInOrdered : Integer;
-  l : TList;
+  l : TList<Pointer>;
   OpSha256 : TRawBytes;
   OpSha256 : TRawBytes;
 begin
 begin
   OpSha256 := op.Sha256;
   OpSha256 := op.Sha256;
@@ -2270,7 +2272,7 @@ begin
 end;
 end;
 
 
 function TOperationsHashTree.IndexOfOpReference(const opReference: TOpReference): Integer;
 function TOperationsHashTree.IndexOfOpReference(const opReference: TOpReference): Integer;
-Var l : TList;
+Var l : TList<Pointer>;
 begin
 begin
   l := FHashTreeOperations.LockList;
   l := FHashTreeOperations.LockList;
   Try
   Try
@@ -2282,7 +2284,7 @@ begin
 end;
 end;
 
 
 function TOperationsHashTree.CountOperationsBySameSignerWithoutFee(account_number: Cardinal): Integer;
 function TOperationsHashTree.CountOperationsBySameSignerWithoutFee(account_number: Cardinal): Integer;
-Var l : TList;
+Var l : TList<Pointer>;
   i : Integer;
   i : Integer;
 begin
 begin
   Result := 0;
   Result := 0;
@@ -2298,13 +2300,13 @@ begin
   End;
   End;
 end;
 end;
 
 
-function TOperationsHashTree.InternalAddOperationToHashTree(list: TList; op: TPCOperation; CalcNewHashTree : Boolean) : Boolean;
+function TOperationsHashTree.InternalAddOperationToHashTree(list: TList<Pointer>; op: TPCOperation; CalcNewHashTree : Boolean) : Boolean;
 Var msCopy : TMemoryStream;
 Var msCopy : TMemoryStream;
   hForNewHash : TRawBytes;
   hForNewHash : TRawBytes;
   P : POperationHashTreeReg;
   P : POperationHashTreeReg;
   PaccData : POperationsHashAccountsData;
   PaccData : POperationsHashAccountsData;
   i,npos,iListSigners : Integer;
   i,npos,iListSigners : Integer;
-  listSigners : TList;
+  listSigners : TList<Cardinal>;
 begin
 begin
   if Not InternalCanAddOperationToHashTree(list,op) then begin
   if Not InternalCanAddOperationToHashTree(list,op) then begin
     Result := False;
     Result := False;
@@ -2342,23 +2344,23 @@ begin
     npos := list.Add(P);
     npos := list.Add(P);
     //
     //
     if Not FindOrderedByOpReference(list,op.GetOpReference,i) then begin
     if Not FindOrderedByOpReference(list,op.GetOpReference,i) then begin
-      FListOrderedByOpReference.Insert(i,TObject(npos));
+      FListOrderedByOpReference.Insert(i, npos);
     end; // TODO: Do not allow duplicate OpReferences?
     end; // TODO: Do not allow duplicate OpReferences?
 
 
     // Improvement: Will allow to add duplicate Operations, so add only first to orderedBySha
     // Improvement: Will allow to add duplicate Operations, so add only first to orderedBySha
     If Not FindOrderedBySha(list,op.Sha256,i) then begin
     If Not FindOrderedBySha(list,op.Sha256,i) then begin
       // Protection: Will add only once
       // Protection: Will add only once
-      FListOrderedBySha256.Insert(i,TObject(npos));
+      FListOrderedBySha256.Insert(i, npos);
     end;
     end;
     // Improvement TOperationsHashTree speed 2.1.6
     // Improvement TOperationsHashTree speed 2.1.6
     // Mantain an ordered Accounts list with data
     // Mantain an ordered Accounts list with data
-    listSigners := TList.Create;
+    listSigners := TList<Cardinal>.Create;
     try
     try
       op.SignerAccounts(listSigners);
       op.SignerAccounts(listSigners);
       for iListSigners:=0 to listSigners.Count-1 do begin
       for iListSigners:=0 to listSigners.Count-1 do begin
-        If Not FindOrderedByAccountData(list,PtrInt(listSigners[iListSigners]),i) then begin
+        If Not FindOrderedByAccountData(list,listSigners[iListSigners],i) then begin
           New(PaccData);
           New(PaccData);
-          PaccData^.account_number:=PtrInt(listSigners[iListSigners]);
+          PaccData^.account_number:=listSigners[iListSigners];
           PaccData^.account_count:=0;
           PaccData^.account_count:=0;
           PaccData^.account_without_fee:=0;
           PaccData^.account_without_fee:=0;
           FListOrderedByAccountsData.Insert(i,PaccData);
           FListOrderedByAccountsData.Insert(i,PaccData);
@@ -2376,10 +2378,10 @@ begin
   If Assigned(FOnChanged) then FOnChanged(Self);
   If Assigned(FOnChanged) then FOnChanged(Self);
 end;
 end;
 
 
-function TOperationsHashTree.InternalCanAddOperationToHashTree(lockedThreadList : TList; op: TPCOperation): Boolean;
+function TOperationsHashTree.InternalCanAddOperationToHashTree(lockedThreadList : TList<Pointer>; op: TPCOperation): Boolean;
 Var PaccData : POperationsHashAccountsData;
 Var PaccData : POperationsHashAccountsData;
   iListSigners,iFound : Integer;
   iListSigners,iFound : Integer;
-  listSigners : TList;
+  listSigners : TList<Cardinal>;
 begin
 begin
   Result := False;
   Result := False;
   // Protections:
   // Protections:
@@ -2387,11 +2389,11 @@ begin
   if (op.OperationFee=0) And (FMax0feeOperationsBySigner>=0) then begin
   if (op.OperationFee=0) And (FMax0feeOperationsBySigner>=0) then begin
     if (FMax0feeOperationsBySigner=0) then Exit // Not allowed 0-fee operations!
     if (FMax0feeOperationsBySigner=0) then Exit // Not allowed 0-fee operations!
     else if (FMax0feeOperationsBySigner>0) then begin
     else if (FMax0feeOperationsBySigner>0) then begin
-      listSigners := TList.Create;
+      listSigners := TList<Cardinal>.Create;
       try
       try
         op.SignerAccounts(listSigners);
         op.SignerAccounts(listSigners);
         for iListSigners:=0 to listSigners.Count-1 do begin
         for iListSigners:=0 to listSigners.Count-1 do begin
-          If FindOrderedByAccountData(lockedThreadList,PtrInt(listSigners[iListSigners]),iFound) then begin
+          If FindOrderedByAccountData(lockedThreadList,(listSigners[iListSigners]),iFound) then begin
             PaccData := FListOrderedByAccountsData[iFound];
             PaccData := FListOrderedByAccountsData[iFound];
             if (PaccData^.account_without_fee>=FMax0feeOperationsBySigner) then Exit; // Limit 0-fee reached
             if (PaccData^.account_without_fee>=FMax0feeOperationsBySigner) then Exit; // Limit 0-fee reached
           end;
           end;
@@ -2404,7 +2406,7 @@ begin
   Result := True;
   Result := True;
 end;
 end;
 
 
-function TOperationsHashTree.FindOrderedBySha(lockedThreadList : TList; const Value: TRawBytes; var Index: Integer): Boolean;
+function TOperationsHashTree.FindOrderedBySha(lockedThreadList : TList<Pointer>; const Value: TRawBytes; var Index: Integer): Boolean;
 var L, H, I : Integer;
 var L, H, I : Integer;
   iLockedThreadListPos : PtrInt;
   iLockedThreadListPos : PtrInt;
   C : Int64;
   C : Int64;
@@ -2431,7 +2433,7 @@ begin
   Index := L;
   Index := L;
 end;
 end;
 
 
-function TOperationsHashTree.FindOrderedByAccountData(lockedThreadList: TList; const account_number: Cardinal; var Index: Integer): Boolean;
+function TOperationsHashTree.FindOrderedByAccountData(lockedThreadList: TList<Pointer>; const account_number: Cardinal; var Index: Integer): Boolean;
 var L, H, I : Integer;
 var L, H, I : Integer;
   C : Int64;
   C : Int64;
 begin
 begin
@@ -2455,7 +2457,7 @@ begin
   Index := L;
   Index := L;
 end;
 end;
 
 
-function TOperationsHashTree.FindOrderedByOpReference(lockedThreadList: TList; const Value: TOpReference; var Index: Integer): Boolean;
+function TOperationsHashTree.FindOrderedByOpReference(lockedThreadList: TList<Pointer>; const Value: TOpReference; var Index: Integer): Boolean;
 var L, H, I : Integer;
 var L, H, I : Integer;
   iLockedThreadListPos : PtrInt;
   iLockedThreadListPos : PtrInt;
   C : Int64;
   C : Int64;
@@ -2542,7 +2544,7 @@ end;
 procedure TOperationsHashTree.MarkVerifiedECDSASignatures(operationsHashTreeToMark: TOperationsHashTree);
 procedure TOperationsHashTree.MarkVerifiedECDSASignatures(operationsHashTreeToMark: TOperationsHashTree);
 var i, iPosInMyList, nMarkedAsGood, nAlreadyMarked : Integer;
 var i, iPosInMyList, nMarkedAsGood, nAlreadyMarked : Integer;
   opToMark, opInMyList : TPCOperation;
   opToMark, opInMyList : TPCOperation;
-  myList, listToMark : TList;
+  myList, listToMark : TList<Pointer>;
 begin
 begin
   // Introduced on Build 4.0.2 to increase speed
   // Introduced on Build 4.0.2 to increase speed
   // Will search each "operationsHashTreeToMark" operation on my current list. If found, will set same FHasValidSignature in order to mark operation in "operationsHashTreeToMark" as verified
   // Will search each "operationsHashTreeToMark" operation on my current list. If found, will set same FHasValidSignature in order to mark operation in "operationsHashTreeToMark" as verified
@@ -2584,7 +2586,7 @@ begin
 end;
 end;
 
 
 function TOperationsHashTree.OperationsCount: Integer;
 function TOperationsHashTree.OperationsCount: Integer;
-Var l : TList;
+Var l : TList<Pointer>;
 begin
 begin
   l := FHashTreeOperations.LockList;
   l := FHashTreeOperations.LockList;
   try
   try
@@ -2596,7 +2598,7 @@ end;
 
 
 procedure TOperationsHashTree.RemoveByOpReference(const opReference: TOpReference);
 procedure TOperationsHashTree.RemoveByOpReference(const opReference: TOpReference);
 var i : Integer;
 var i : Integer;
-  l : TList;
+  l : TList<Pointer>;
   iLockedThreadListPos : PtrInt;
   iLockedThreadListPos : PtrInt;
 begin
 begin
   l := FHashTreeOperations.LockList;
   l := FHashTreeOperations.LockList;
@@ -2613,7 +2615,7 @@ end;
 function TOperationsHashTree.SaveOperationsHashTreeToStream(Stream: TStream; SaveToStorage: Boolean): Boolean;
 function TOperationsHashTree.SaveOperationsHashTreeToStream(Stream: TStream; SaveToStorage: Boolean): Boolean;
 Var c, i, OpType: Cardinal;
 Var c, i, OpType: Cardinal;
   bcop: TPCOperation;
   bcop: TPCOperation;
-  l : TList;
+  l : TList<Pointer>;
 begin
 begin
   l := FHashTreeOperations.LockList;
   l := FHashTreeOperations.LockList;
   Try
   Try
@@ -2863,10 +2865,10 @@ begin
   Result := Cardinal(opReference);
   Result := Cardinal(opReference);
 end;
 end;
 
 
-procedure TPCOperation.SignerAccounts(list: TList);
+procedure TPCOperation.SignerAccounts(list: TList<Cardinal>);
 begin
 begin
   list.Clear;
   list.Clear;
-  list.Add(TObject(SignerAccount));
+  list.Add(SignerAccount);
 end;
 end;
 
 
 class function TPCOperation.DecodeOperationHash(const operationHash: TRawBytes;
 class function TPCOperation.DecodeOperationHash(const operationHash: TRawBytes;
@@ -3232,12 +3234,12 @@ begin
 end;
 end;
 
 
 function TPCOperation.IsAffectedAccount(account: Cardinal): Boolean;
 function TPCOperation.IsAffectedAccount(account: Cardinal): Boolean;
-Var l : TList;
+Var l : TList<Cardinal>;
 begin
 begin
-  l := TList.Create;
+  l := TList<Cardinal>.Create;
   Try
   Try
     AffectedAccounts(l);
     AffectedAccounts(l);
-    Result := (l.IndexOf(TObject(account))>=0);
+    Result := (l.IndexOf(account)>=0);
   finally
   finally
     l.Free;
     l.Free;
   end;
   end;
@@ -3297,7 +3299,7 @@ end;
 procedure TOperationsResumeList.Clear;
 procedure TOperationsResumeList.Clear;
 Var P : POperationResume;
 Var P : POperationResume;
   i : Integer;
   i : Integer;
-  l : TList;
+  l : TList<Pointer>;
 begin
 begin
   l := FList.LockList;
   l := FList.LockList;
   try
   try
@@ -3312,7 +3314,7 @@ begin
 end;
 end;
 
 
 function TOperationsResumeList.Count: Integer;
 function TOperationsResumeList.Count: Integer;
-Var l : TList;
+Var l : TList<Pointer>;
 begin
 begin
   l := FList.LockList;
   l := FList.LockList;
   Try
   Try
@@ -3324,12 +3326,12 @@ end;
 
 
 constructor TOperationsResumeList.Create;
 constructor TOperationsResumeList.Create;
 begin
 begin
-  FList := TPCThreadList.Create('TOperationsResumeList_List');
+  FList := TPCThreadList<Pointer>.Create('TOperationsResumeList_List');
 end;
 end;
 
 
 procedure TOperationsResumeList.Delete(index: Integer);
 procedure TOperationsResumeList.Delete(index: Integer);
 Var P : POperationResume;
 Var P : POperationResume;
-  l : TList;
+  l : TList<Pointer>;
 begin
 begin
   l := FList.LockList;
   l := FList.LockList;
   Try
   Try
@@ -3349,7 +3351,7 @@ begin
 end;
 end;
 
 
 function TOperationsResumeList.GetOperationResume(index: Integer): TOperationResume;
 function TOperationsResumeList.GetOperationResume(index: Integer): TOperationResume;
-Var l : TList;
+Var l : TList<Pointer>;
 begin
 begin
   l := FList.LockList;
   l := FList.LockList;
   try
   try

+ 8 - 3
src/core/UCrypto.pas

@@ -270,8 +270,7 @@ end;
 
 
 function TECPrivateKey.GetPublicKey: TECDSA_Public;
 function TECPrivateKey.GetPublicKey: TECDSA_Public;
 {$IFDEF Use_OpenSSL}
 {$IFDEF Use_OpenSSL}
-var ps : PAnsiChar;
-  BNx,BNy : PBIGNUM;
+var BNx,BNy : PBIGNUM;
   ctx : PBN_CTX;
   ctx : PBN_CTX;
 {$ENDIF}
 {$ENDIF}
 begin
 begin
@@ -315,6 +314,9 @@ Var ms : TStream;
   LNewPrivateKeyInfo : TECPrivateKeyInfo;
   LNewPrivateKeyInfo : TECPrivateKeyInfo;
 begin
 begin
   Result := Nil;
   Result := Nil;
+  LNewPrivateKeyInfo.EC_OpenSSL_NID := 0;
+  LNewPrivateKeyInfo.EC_KEY_Ptr := Nil;
+  LNewPrivateKeyInfo.RAW_PrivKey := Nil;
   ms := TMemoryStream.Create;
   ms := TMemoryStream.Create;
   Try
   Try
     ms.WriteBuffer(raw[Low(raw)],Length(raw));
     ms.WriteBuffer(raw[Low(raw)],Length(raw));
@@ -425,6 +427,9 @@ begin
   if Assigned(FPrivateKeyInfo.EC_KEY_Ptr) then EC_KEY_free(FPrivateKeyInfo.EC_KEY_Ptr);
   if Assigned(FPrivateKeyInfo.EC_KEY_Ptr) then EC_KEY_free(FPrivateKeyInfo.EC_KEY_Ptr);
   {$ENDIF}
   {$ENDIF}
   FPrivateKeyInfo := Value;
   FPrivateKeyInfo := Value;
+  {$IFNDEF Use_OpenSSL}
+  FPrivateKeyInfo.EC_KEY_Ptr := Nil;
+  {$ENDIF}
 end;
 end;
 
 
 function TECPrivateKey.SetPrivateKeyFromHexa(AEC_OpenSSL_NID : Word; const hexa : String) : Boolean;
 function TECPrivateKey.SetPrivateKeyFromHexa(AEC_OpenSSL_NID : Word; const hexa : String) : Boolean;
@@ -447,7 +452,7 @@ begin
     if Assigned(FPrivateKeyInfo.EC_KEY_Ptr) then EC_KEY_free(FPrivateKeyInfo.EC_KEY_Ptr);
     if Assigned(FPrivateKeyInfo.EC_KEY_Ptr) then EC_KEY_free(FPrivateKeyInfo.EC_KEY_Ptr);
     FPrivateKeyInfo.EC_KEY_Ptr := Nil;
     FPrivateKeyInfo.EC_KEY_Ptr := Nil;
 
 
-    FPrivateKeyInfo.EC_OpenSSL_NID := EC_OpenSSL_NID;
+    FPrivateKeyInfo.EC_OpenSSL_NID := AEC_OpenSSL_NID;
     FPrivateKeyInfo.EC_KEY_Ptr := EC_KEY_new_by_curve_name(EC_OpenSSL_NID);
     FPrivateKeyInfo.EC_KEY_Ptr := EC_KEY_new_by_curve_name(EC_OpenSSL_NID);
     If Not Assigned(FPrivateKeyInfo.EC_KEY_Ptr) then Exit;
     If Not Assigned(FPrivateKeyInfo.EC_KEY_Ptr) then Exit;
     if EC_KEY_set_private_key(FPrivateKeyInfo.EC_KEY_Ptr,bn)<>1 then raise ECryptoException.Create('Invalid num to set as private key');
     if EC_KEY_set_private_key(FPrivateKeyInfo.EC_KEY_Ptr,bn)<>1 then raise ECryptoException.Create('Invalid num to set as private key');

+ 9 - 7
src/core/ULog.pas

@@ -23,7 +23,9 @@ unit ULog;
 interface
 interface
 
 
 uses
 uses
-  Classes, UThread, SyncObjs, UConst;
+  Classes, UThread, SyncObjs, UConst,
+  {$IFNDEF FPC}System.Generics.Collections{$ELSE}Generics.Collections{$ENDIF};
+
 
 
 type
 type
   TLogType = (ltinfo, ltupdate, lterror, ltdebug);
   TLogType = (ltinfo, ltupdate, lterror, ltdebug);
@@ -53,7 +55,7 @@ type
 
 
   TLog = Class(TComponent)
   TLog = Class(TComponent)
   private
   private
-    FLogDataList : TThreadList;
+    FLogDataList : TThreadList<Pointer>;
     FOnNewLog: TNewLogEvent;
     FOnNewLog: TNewLogEvent;
     FOnInThreadNewLog : TNewLogEvent;
     FOnInThreadNewLog : TNewLogEvent;
     FFileStream : TFileStream;
     FFileStream : TFileStream;
@@ -87,7 +89,7 @@ implementation
 
 
 uses SysUtils;
 uses SysUtils;
 
 
-var _logs : TList;
+var _logs : TList<TLog>;
 Type PLogData = ^TLogData;
 Type PLogData = ^TLogData;
 
 
 { TLog }
 { TLog }
@@ -96,13 +98,13 @@ constructor TLog.Create(AOwner: TComponent);
 begin
 begin
   FLock := TCriticalSection.Create;
   FLock := TCriticalSection.Create;
   FProcessGlobalLogs := true;
   FProcessGlobalLogs := true;
-  FLogDataList := TThreadList.Create;
+  FLogDataList := TThreadList<Pointer>.Create;
   FFileStream := Nil;
   FFileStream := Nil;
   FFileName := '';
   FFileName := '';
   FSaveTypes := CT_TLogTypes_DEFAULT;
   FSaveTypes := CT_TLogTypes_DEFAULT;
   FOnInThreadNewLog:=Nil;
   FOnInThreadNewLog:=Nil;
   FOnNewLog:=Nil;
   FOnNewLog:=Nil;
-  if (Not assigned(_logs)) then _logs := TList.Create;
+  if (Not assigned(_logs)) then _logs := TList<TLog>.Create;
   _logs.Add(self);
   _logs.Add(self);
   FThreadSafeLogEvent := TThreadSafeLogEvent.Create(true);
   FThreadSafeLogEvent := TThreadSafeLogEvent.Create(true);
   FThreadSafeLogEvent.FLog := Self;
   FThreadSafeLogEvent.FLog := Self;
@@ -112,7 +114,7 @@ end;
 
 
 destructor TLog.Destroy;
 destructor TLog.Destroy;
 var
 var
-  l : TList;
+  l : TList<Pointer>;
   i : Integer;
   i : Integer;
   P : PLogData;
   P : PLogData;
 begin
 begin
@@ -220,7 +222,7 @@ begin
 end;
 end;
 
 
 procedure TThreadSafeLogEvent.SynchronizedProcess;
 procedure TThreadSafeLogEvent.SynchronizedProcess;
-Var l : TList;
+Var l : TList<Pointer>;
   i : Integer;
   i : Integer;
   P : PLogData;
   P : PLogData;
 begin
 begin

+ 11 - 9
src/core/UNetProtection.pas

@@ -33,7 +33,9 @@ unit UNetProtection;
 
 
 interface
 interface
 
 
-Uses SysUtils, Classes, UJSONFunctions, UThread, ULog, UTime;
+Uses SysUtils, Classes, UJSONFunctions, UThread, ULog, UTime,
+  {$IFNDEF FPC}System.Generics.Collections{$ELSE}Generics.Collections{$ENDIF};
+
 
 
 Type
 Type
   TIpInfo = Record
   TIpInfo = Record
@@ -51,11 +53,11 @@ Type
 
 
   TIpInfos = Class
   TIpInfos = Class
   private
   private
-    FThreadList : TPCThreadList;
+    FThreadList : TPCThreadList<Pointer>;
     FMaxStatsLifetime: Integer;
     FMaxStatsLifetime: Integer;
     FMaxStatsCount: Integer;
     FMaxStatsCount: Integer;
     FDeletedStatsCount: Int64;
     FDeletedStatsCount: Int64;
-    function Find(lockedList : TList; const ip : String; var Index: Integer): Boolean;
+    function Find(lockedList : TList<Pointer>; const ip : String; var Index: Integer): Boolean;
     procedure SetMaxStatsLifetime(const Value: Integer);
     procedure SetMaxStatsLifetime(const Value: Integer);
     procedure CleanLastStatsByUpdatedTimestamp(minTimestamp : Integer);
     procedure CleanLastStatsByUpdatedTimestamp(minTimestamp : Integer);
     procedure SetMaxStatsCount(const Value: Integer);
     procedure SetMaxStatsCount(const Value: Integer);
@@ -85,7 +87,7 @@ procedure TIpInfos.CleanLastStatsByUpdatedTimestamp(minTimestamp: Integer);
 var jsonOpType, relJsonOpType, relJsonNetTransferType : TPCJSONObject;
 var jsonOpType, relJsonOpType, relJsonNetTransferType : TPCJSONObject;
   lasts : TPCJSONArray;
   lasts : TPCJSONArray;
   iIp, i,j,k : Integer;
   iIp, i,j,k : Integer;
-  list : TList;
+  list : TList<Pointer>;
   p : PIpInfo;
   p : PIpInfo;
 begin
 begin
   list := FThreadList.LockList;
   list := FThreadList.LockList;
@@ -124,7 +126,7 @@ end;
 procedure TIpInfos.Clear;
 procedure TIpInfos.Clear;
 var p : PIpInfo;
 var p : PIpInfo;
   i : Integer;
   i : Integer;
-  list : TList;
+  list : TList<Pointer>;
 begin
 begin
   list := FThreadList.LockList;
   list := FThreadList.LockList;
   Try
   Try
@@ -148,7 +150,7 @@ end;
 
 
 constructor TIpInfos.Create;
 constructor TIpInfos.Create;
 begin
 begin
-  FThreadList := TPCThreadList.Create(Self.ClassName);
+  FThreadList := TPCThreadList<Pointer>.Create(Self.ClassName);
   FMaxStatsLifetime := 60*60*24; // Last values by 24 hours by default
   FMaxStatsLifetime := 60*60*24; // Last values by 24 hours by default
   FMaxStatsCount := 1000; // Max 1000 last stats by default
   FMaxStatsCount := 1000; // Max 1000 last stats by default
   FDeletedStatsCount := 0;
   FDeletedStatsCount := 0;
@@ -161,7 +163,7 @@ begin
   inherited;
   inherited;
 end;
 end;
 
 
-function TIpInfos.Find(lockedList : TList; const ip: String; var Index: Integer): Boolean;
+function TIpInfos.Find(lockedList : TList<Pointer>; const ip: String; var Index: Integer): Boolean;
 var L, H, I, C: Integer;
 var L, H, I, C: Integer;
   PN : PIpInfo;
   PN : PIpInfo;
 begin
 begin
@@ -187,7 +189,7 @@ begin
 end;
 end;
 
 
 function TIpInfos.Lock(index: Integer): TIpInfo;
 function TIpInfos.Lock(index: Integer): TIpInfo;
-var list : TList;
+var list : TList<Pointer>;
 begin
 begin
   list := FThreadList.LockList;
   list := FThreadList.LockList;
   if (list.Count>index) then begin
   if (list.Count>index) then begin
@@ -229,7 +231,7 @@ begin
 end;
 end;
 
 
 function TIpInfos.Lock(const AIp: String; MarkAsUpdated: Boolean): TPCJSONObject;
 function TIpInfos.Lock(const AIp: String; MarkAsUpdated: Boolean): TPCJSONObject;
-var list : TList;
+var list : TList<Pointer>;
   i : Integer;
   i : Integer;
   p : PIpInfo;
   p : PIpInfo;
 begin
 begin

+ 104 - 87
src/core/UNetProtocol.pas

@@ -31,6 +31,8 @@ Uses
 {$ENDIF}
 {$ENDIF}
   UBlockChain, Classes, SysUtils, UAccounts, UThread,
   UBlockChain, Classes, SysUtils, UAccounts, UThread,
   UCrypto, UTCPIP, SyncObjs, UBaseTypes, UCommon, UPCOrderedLists,
   UCrypto, UTCPIP, SyncObjs, UBaseTypes, UCommon, UPCOrderedLists,
+  {$IFNDEF FPC}System.Generics.Collections,System.Generics.Defaults
+  {$ELSE}Generics.Collections,Generics.Defaults{$ENDIF},
   UNetProtection;
   UNetProtection;
 
 
 {$I config.inc}
 {$I config.inc}
@@ -141,8 +143,8 @@ Type
     FAllowDeleteOnClean: Boolean;
     FAllowDeleteOnClean: Boolean;
     FNetData : TNetData;
     FNetData : TNetData;
     FCritical : TPCCriticalSection;
     FCritical : TPCCriticalSection;
-    FListByIp : TList;
-    FListByNetConnection : TList;
+    FListByIp : TList<Pointer>;
+    FListByNetConnection : TList<Pointer>;
     Procedure SecuredDeleteFromListByIp(index : Integer);
     Procedure SecuredDeleteFromListByIp(index : Integer);
     Function SecuredFindByIp(const ip : String; port : Word; var Index: Integer): Boolean;
     Function SecuredFindByIp(const ip : String; port : Word; var Index: Integer): Boolean;
     Function SecuredFindByNetConnection(const search : TNetConnection; var Index: Integer): Boolean;
     Function SecuredFindByNetConnection(const search : TNetConnection; var Index: Integer): Boolean;
@@ -155,7 +157,7 @@ Type
     Function Count : Integer;
     Function Count : Integer;
     Function CleanBlackList(forceCleanAll : Boolean) : Integer;
     Function CleanBlackList(forceCleanAll : Boolean) : Integer;
     procedure CleanNodeServersList;
     procedure CleanNodeServersList;
-    Function LockList : TList;
+    Function LockList : TList<Pointer>;
     Procedure UnlockList;
     Procedure UnlockList;
     function IsBlackListed(const ip: String): Boolean;
     function IsBlackListed(const ip: String): Boolean;
     function GetNodeServerAddress(const ip : String; port:Word; CanAdd : Boolean; var nodeServerAddress : TNodeServerAddress) : Boolean;
     function GetNodeServerAddress(const ip : String; port:Word; CanAdd : Boolean; var nodeServerAddress : TNodeServerAddress) : Boolean;
@@ -234,11 +236,11 @@ Type
 
 
   TNetworkAdjustedTime = Class
   TNetworkAdjustedTime = Class
   private
   private
-    FTimesList : TPCThreadList;
+    FTimesList : TPCThreadList<Pointer>;
     FTimeOffset : Integer;
     FTimeOffset : Integer;
     FTotalCounter : Integer;
     FTotalCounter : Integer;
-    Function IndexOfClientIp(list : TList; const clientIp : String) : Integer;
-    Procedure UpdateMedian(list : TList);
+    Function IndexOfClientIp(list : TList<Pointer>; const clientIp : String) : Integer;
+    Procedure UpdateMedian(list : TList<Pointer>);
   public
   public
     constructor Create;
     constructor Create;
     destructor Destroy; override;
     destructor Destroy; override;
@@ -260,11 +262,11 @@ Type
     FMinServersConnected: Integer;
     FMinServersConnected: Integer;
     FNetDataNotifyEventsThread : TNetDataNotifyEventsThread;
     FNetDataNotifyEventsThread : TNetDataNotifyEventsThread;
     FNodePrivateKey : TECPrivateKey;
     FNodePrivateKey : TECPrivateKey;
-    FNetConnections : TPCThreadList;
+    FNetConnections : TPCThreadList<TNetConnection>;
     FNodeServersAddresses : TOrderedServerAddressListTS;
     FNodeServersAddresses : TOrderedServerAddressListTS;
     FLastRequestId : Cardinal;
     FLastRequestId : Cardinal;
     FOnProcessReservedAreaMessage: TProcessReservedAreaMessage;
     FOnProcessReservedAreaMessage: TProcessReservedAreaMessage;
-    FRegisteredRequests : TPCThreadList;
+    FRegisteredRequests : TPCThreadList<Pointer>;
     FIsDiscoveringServers : Boolean;
     FIsDiscoveringServers : Boolean;
     FLockGettingNewBlockChainFromClient : TPCCriticalSection;
     FLockGettingNewBlockChainFromClient : TPCCriticalSection;
     FNewBlockChainFromClientStatus : String;
     FNewBlockChainFromClientStatus : String;
@@ -330,7 +332,7 @@ Type
     procedure OnReadingNewSafeboxProgressNotify(sender : TObject; const mesage : String; curPos, totalCount : Int64);
     procedure OnReadingNewSafeboxProgressNotify(sender : TObject; const mesage : String; curPos, totalCount : Int64);
     Procedure GetNewBlockChainFromClient(Connection : TNetConnection; const why : String);
     Procedure GetNewBlockChainFromClient(Connection : TNetConnection; const why : String);
     Property NodeServersAddresses : TOrderedServerAddressListTS read FNodeServersAddresses;
     Property NodeServersAddresses : TOrderedServerAddressListTS read FNodeServersAddresses;
-    Property NetConnections : TPCThreadList read FNetConnections;
+    Property NetConnections : TPCThreadList<TNetConnection> read FNetConnections;
     Property NetStatistics : TNetStatistics read FNetStatistics;
     Property NetStatistics : TNetStatistics read FNetStatistics;
     Property IsDiscoveringServers : Boolean read FIsDiscoveringServers;
     Property IsDiscoveringServers : Boolean read FIsDiscoveringServers;
     function IsGettingNewBlockChainFromClient(var status : String) : Boolean;
     function IsGettingNewBlockChainFromClient(var status : String) : Boolean;
@@ -612,8 +614,8 @@ constructor TOrderedServerAddressListTS.Create(ANetData : TNetData);
 begin
 begin
   FNetData := ANetData;
   FNetData := ANetData;
   FCritical := TPCCriticalSection.Create(Classname);
   FCritical := TPCCriticalSection.Create(Classname);
-  FListByIp := TList.Create;
-  FListByNetConnection := TList.Create;
+  FListByIp := TList<Pointer>.Create;
+  FListByNetConnection := TList<Pointer>.Create;
   FAllowDeleteOnClean := True;
   FAllowDeleteOnClean := True;
 end;
 end;
 
 
@@ -669,7 +671,7 @@ begin
 end;
 end;
 
 
 procedure TOrderedServerAddressListTS.GetNodeServersToConnnect(maxNodes: Integer; useArray : Boolean; var nsa: TNodeServerAddressArray);
 procedure TOrderedServerAddressListTS.GetNodeServersToConnnect(maxNodes: Integer; useArray : Boolean; var nsa: TNodeServerAddressArray);
-  Procedure sw(l : TList);
+  Procedure sw(l : TList<Pointer>);
   Var i,j,x,y : Integer;
   Var i,j,x,y : Integer;
   begin
   begin
     if l.Count<=1 then exit;
     if l.Count<=1 then exit;
@@ -688,12 +690,12 @@ procedure TOrderedServerAddressListTS.GetNodeServersToConnnect(maxNodes: Integer
   End;
   End;
 Var i,j, iStart : Integer;
 Var i,j, iStart : Integer;
   P : PNodeServerAddress;
   P : PNodeServerAddress;
-  l : TList;
+  l : TList<Pointer>;
   ns : TNodeServerAddress;
   ns : TNodeServerAddress;
 begin
 begin
   FCritical.Acquire;
   FCritical.Acquire;
   Try
   Try
-    l := TList.Create;
+    l := TList<Pointer>.Create;
     Try
     Try
       if useArray then begin
       if useArray then begin
         for i := 0 to High(nsa) do begin
         for i := 0 to High(nsa) do begin
@@ -828,7 +830,7 @@ begin
   End;
   End;
 end;
 end;
 
 
-function TOrderedServerAddressListTS.LockList: TList;
+function TOrderedServerAddressListTS.LockList: TList<Pointer>;
 begin
 begin
   FCritical.Acquire;
   FCritical.Acquire;
   Result := FListByIp;
   Result := FListByIp;
@@ -966,13 +968,12 @@ Type PNetRequestRegistered = ^TNetRequestRegistered;
 procedure TNetData.AddServer(NodeServerAddress: TNodeServerAddress);
 procedure TNetData.AddServer(NodeServerAddress: TNodeServerAddress);
 Var P : PNodeServerAddress;
 Var P : PNodeServerAddress;
   i : Integer;
   i : Integer;
-  l : TList;
   currunixtimestamp : Cardinal;
   currunixtimestamp : Cardinal;
   nsa : TNodeServerAddress;
   nsa : TNodeServerAddress;
 begin
 begin
   if (trim(NodeServerAddress.ip)='')
   if (trim(NodeServerAddress.ip)='')
      or (SameText(NodeServerAddress.ip,'localhost'))
      or (SameText(NodeServerAddress.ip,'localhost'))
-     or (SameText('127.',Copy(NodeServerAddress.ip,1,4))) then Exit;
+     or (SameText('127.',NodeServerAddress.ip.Substring(0,4))) then Exit;
 
 
   if (NodeServerAddress.port<=0) then NodeServerAddress.port := CT_NetServer_Port
   if (NodeServerAddress.port<=0) then NodeServerAddress.port := CT_NetServer_Port
   else if (NodeServerAddress.port<>CT_NetServer_Port) then exit;
   else if (NodeServerAddress.port<>CT_NetServer_Port) then exit;
@@ -999,11 +1000,11 @@ begin
 end;
 end;
 
 
 function TNetData.Connection(index: Integer): TNetConnection;
 function TNetData.Connection(index: Integer): TNetConnection;
-Var l : TList;
+Var l : TList<TNetConnection>;
 begin
 begin
   l := FNetConnections.LockList;
   l := FNetConnections.LockList;
   try
   try
-    Result := TNetConnection( l[index] );
+    Result := ( l[index] );
   finally
   finally
     FNetConnections.UnlockList;
     FNetConnections.UnlockList;
   end;
   end;
@@ -1011,7 +1012,7 @@ end;
 
 
 function TNetData.ConnectionExists(ObjectPointer: TObject): Boolean;
 function TNetData.ConnectionExists(ObjectPointer: TObject): Boolean;
 var i : Integer;
 var i : Integer;
-  l : TList;
+  l : TList<TNetConnection>;
 begin
 begin
   Result := false;
   Result := false;
   l := FNetConnections.LockList;
   l := FNetConnections.LockList;
@@ -1029,7 +1030,7 @@ end;
 
 
 function TNetData.ConnectionExistsAndActive(ObjectPointer: TObject): Boolean;
 function TNetData.ConnectionExistsAndActive(ObjectPointer: TObject): Boolean;
 var i : Integer;
 var i : Integer;
-  l : TList;
+  l : TList<TNetConnection>;
 begin
 begin
   Result := false;
   Result := false;
   l := FNetConnections.LockList;
   l := FNetConnections.LockList;
@@ -1047,7 +1048,7 @@ end;
 
 
 function TNetData.ConnectionLock(Sender : TObject; ObjectPointer: TObject; MaxWaitMiliseconds : Cardinal) : Boolean;
 function TNetData.ConnectionLock(Sender : TObject; ObjectPointer: TObject; MaxWaitMiliseconds : Cardinal) : Boolean;
 var i : Integer;
 var i : Integer;
-  l : TList;
+  l : TList<TNetConnection>;
   nc : TNetConnection;
   nc : TNetConnection;
   tc : TTickCount;
   tc : TTickCount;
 begin
 begin
@@ -1079,7 +1080,7 @@ end;
 
 
 function TNetData.ConnectionsCount(CountOnlyNetClients : Boolean): Integer;
 function TNetData.ConnectionsCount(CountOnlyNetClients : Boolean): Integer;
 var i : Integer;
 var i : Integer;
-  l : TList;
+  l : TList<TNetConnection>;
 begin
 begin
   l := FNetConnections.LockList;
   l := FNetConnections.LockList;
   try
   try
@@ -1095,7 +1096,7 @@ begin
 end;
 end;
 
 
 function TNetData.ConnectionsCountAll: Integer;
 function TNetData.ConnectionsCountAll: Integer;
-Var l : TList;
+Var l : TList<TNetConnection>;
 begin
 begin
   l := FNetConnections.LockList;
   l := FNetConnections.LockList;
   try
   try
@@ -1106,7 +1107,7 @@ begin
 end;
 end;
 
 
 function TNetData.ConnectionsCountClients: Integer;
 function TNetData.ConnectionsCountClients: Integer;
-Var l : TList; i : Integer;
+Var l : TList<TNetConnection>; i : Integer;
 begin
 begin
   Result := 0;
   Result := 0;
   l := FNetConnections.LockList;
   l := FNetConnections.LockList;
@@ -1120,7 +1121,7 @@ begin
 end;
 end;
 
 
 function TNetData.ConnectionsCountServerClients: Integer;
 function TNetData.ConnectionsCountServerClients: Integer;
-Var l : TList; i : Integer;
+Var l : TList<TNetConnection>; i : Integer;
 begin
 begin
   Result := 0;
   Result := 0;
   l := FNetConnections.LockList;
   l := FNetConnections.LockList;
@@ -1135,7 +1136,7 @@ end;
 
 
 procedure TNetData.ConnectionUnlock(ObjectPointer: TObject);
 procedure TNetData.ConnectionUnlock(ObjectPointer: TObject);
 var i : Integer;
 var i : Integer;
-  l : TList;
+  l : TList<TNetConnection>;
   nc : TNetConnection;
   nc : TNetConnection;
 begin
 begin
   l := FNetConnections.LockList;
   l := FNetConnections.LockList;
@@ -1178,10 +1179,10 @@ begin
   FOnReceivedHelloMessage := Nil;
   FOnReceivedHelloMessage := Nil;
   FOnGetNewBlockchainFromClientDownloadNewSafebox := Nil;
   FOnGetNewBlockchainFromClientDownloadNewSafebox := Nil;
   FIsDiscoveringServers := false;
   FIsDiscoveringServers := false;
-  FRegisteredRequests := TPCThreadList.Create('TNetData_RegisteredRequests');
+  FRegisteredRequests := TPCThreadList<Pointer>.Create('TNetData_RegisteredRequests');
   FNodeServersAddresses := TOrderedServerAddressListTS.Create(Self);
   FNodeServersAddresses := TOrderedServerAddressListTS.Create(Self);
   FLastRequestId := 0;
   FLastRequestId := 0;
-  FNetConnections := TPCThreadList.Create('TNetData_NetConnections');
+  FNetConnections := TPCThreadList<TNetConnection>.Create('TNetData_NetConnections');
   FLockGettingNewBlockChainFromClient := TPCCriticalSection.Create('LockGettingNewBlockChainFromClient');
   FLockGettingNewBlockChainFromClient := TPCCriticalSection.Create('LockGettingNewBlockChainFromClient');
   FNewBlockChainFromClientStatus := '';
   FNewBlockChainFromClientStatus := '';
   FNodePrivateKey := TECPrivateKey.Create;
   FNodePrivateKey := TECPrivateKey.Create;
@@ -1204,7 +1205,7 @@ begin
 end;
 end;
 
 
 destructor TNetData.Destroy;
 destructor TNetData.Destroy;
-Var l : TList;
+Var l : TList<TNetConnection>;
   i : Integer;
   i : Integer;
   tdc : TThreadDiscoverConnection;
   tdc : TThreadDiscoverConnection;
 begin
 begin
@@ -1270,12 +1271,12 @@ end;
 
 
 procedure TNetData.DisconnectClients;
 procedure TNetData.DisconnectClients;
 var i : Integer;
 var i : Integer;
-  l : TList;
+  l : TList<TNetConnection>;
 begin
 begin
   l := FNetConnections.LockList;
   l := FNetConnections.LockList;
   Try
   Try
     for i := l.Count - 1 downto 0 do begin
     for i := l.Count - 1 downto 0 do begin
-      if TObject(l[i]) is TNetClient then begin
+      if (l[i] is TNetClient) then begin
         TNetClient(l[i]).Connected := false;
         TNetClient(l[i]).Connected := false;
         TNetClient(l[i]).FinalizeConnection;
         TNetClient(l[i]).FinalizeConnection;
       end;
       end;
@@ -1298,20 +1299,8 @@ begin
 end;
 end;
 
 
 procedure TNetData.DiscoverServers;
 procedure TNetData.DiscoverServers;
-  Procedure sw(l : TList);
-  Var i,j,x,y : Integer;
-  begin
-    if l.Count<=1 then exit;
-    j := Random(l.Count)*3;
-    for i := 0 to j do begin
-      x := Random(l.Count);
-      y := Random(l.Count);
-      if x<>y then l.Exchange(x,y);
-    end;
-  end;
 Var P : PNodeServerAddress;
 Var P : PNodeServerAddress;
   i,j,k : Integer;
   i,j,k : Integer;
-  l,lns : TList;
   tdc : TThreadDiscoverConnection;
   tdc : TThreadDiscoverConnection;
   canAdd : Boolean;
   canAdd : Boolean;
   nsa : TNodeServerAddressArray;
   nsa : TNodeServerAddressArray;
@@ -1430,7 +1419,7 @@ begin
 end;
 end;
 
 
 function TNetData.FindConnectionByClientRandomValue(Sender: TNetConnection): TNetConnection;
 function TNetData.FindConnectionByClientRandomValue(Sender: TNetConnection): TNetConnection;
-Var l : TList;
+Var l : TList<TNetConnection>;
   i : Integer;
   i : Integer;
 begin
 begin
   l := FNetConnections.LockList;
   l := FNetConnections.LockList;
@@ -1446,7 +1435,7 @@ begin
 end;
 end;
 
 
 function TNetData.GetConnection(index: Integer; var NetConnection : TNetConnection) : Boolean;
 function TNetData.GetConnection(index: Integer; var NetConnection : TNetConnection) : Boolean;
-Var l : TList;
+Var l : TList<TNetConnection>;
 begin
 begin
   Result := false; NetConnection := Nil;
   Result := false; NetConnection := Nil;
   l := FNetConnections.LockList;
   l := FNetConnections.LockList;
@@ -1465,7 +1454,7 @@ procedure TNetData.GetNewBlockChainFromClient(Connection: TNetConnection;
   const why: String);
   const why: String);
 Const CT_LogSender = 'GetNewBlockChainFromClient';
 Const CT_LogSender = 'GetNewBlockChainFromClient';
 
 
-  function Do_GetOperationsBlock(AssignToBank : TPCBank; block_start,block_end, MaxWaitMilliseconds : Cardinal; OnlyOperationBlock : Boolean; BlocksList : TList) : Boolean;
+  function Do_GetOperationsBlock(AssignToBank : TPCBank; block_start,block_end, MaxWaitMilliseconds : Cardinal; OnlyOperationBlock : Boolean; BlocksList : TList<TPCOperationsComp>) : Boolean;
   Var SendData,ReceiveData : TMemoryStream;
   Var SendData,ReceiveData : TMemoryStream;
     headerdata : TNetHeaderData;
     headerdata : TNetHeaderData;
     op : TPCOperationsComp;
     op : TPCOperationsComp;
@@ -1526,11 +1515,11 @@ Const CT_LogSender = 'GetNewBlockChainFromClient';
   end;
   end;
 
 
   function Do_GetOperationBlock(block, MaxWaitMilliseconds : Cardinal; var OperationBlock : TOperationBlock) : Boolean;
   function Do_GetOperationBlock(block, MaxWaitMilliseconds : Cardinal; var OperationBlock : TOperationBlock) : Boolean;
-  Var BlocksList : TList;
+  Var BlocksList : TList<TPCOperationsComp>;
     i : Integer;
     i : Integer;
   begin
   begin
     OperationBlock := CT_OperationBlock_NUL;
     OperationBlock := CT_OperationBlock_NUL;
-    BlocksList := TList.Create;
+    BlocksList := TList<TPCOperationsComp>.Create;
     try
     try
       Result := Do_GetOperationsBlock(TNode.Node.Bank,block,block,MaxWaitMilliseconds,True,BlocksList);
       Result := Do_GetOperationsBlock(TNode.Node.Bank,block,block,MaxWaitMilliseconds,True,BlocksList);
       // Build 2.1.7 - Included protection agains not good block received
       // Build 2.1.7 - Included protection agains not good block received
@@ -1551,13 +1540,13 @@ Const CT_LogSender = 'GetNewBlockChainFromClient';
     ant_nblock : Int64;
     ant_nblock : Int64;
     auxBlock, sbBlock : TOperationBlock;
     auxBlock, sbBlock : TOperationBlock;
     distinctmax,distinctmin : Cardinal;
     distinctmax,distinctmin : Cardinal;
-    BlocksList : TList;
+    BlocksList : TList<TPCOperationsComp>;
     errors : String;
     errors : String;
   Begin
   Begin
     Result := false;
     Result := false;
     OperationBlock := CT_OperationBlock_NUL;
     OperationBlock := CT_OperationBlock_NUL;
     repeat
     repeat
-      BlocksList := TList.Create;
+      BlocksList := TList<TPCOperationsComp>.Create;
       try
       try
         If Not Do_GetOperationsBlock(Nil,min,max,20000,true,BlocksList) then exit;
         If Not Do_GetOperationsBlock(Nil,min,max,20000,true,BlocksList) then exit;
         if (BlocksList.Count=0) then begin
         if (BlocksList.Count=0) then begin
@@ -1604,7 +1593,7 @@ Const CT_LogSender = 'GetNewBlockChainFromClient';
   End;
   End;
 
 
   procedure GetNewBank(start_block : Int64);
   procedure GetNewBank(start_block : Int64);
-  Var BlocksList : TList;
+  Var BlocksList : TList<TPCOperationsComp>;
     i : Integer;
     i : Integer;
     OpComp,OpExecute : TPCOperationsComp;
     OpComp,OpExecute : TPCOperationsComp;
     oldBlockchainOperations : TOperationsHashTree;
     oldBlockchainOperations : TOperationsHashTree;
@@ -1653,7 +1642,7 @@ Const CT_LogSender = 'GetNewBlockChainFromClient';
       // Receive new blocks:
       // Receive new blocks:
       finished := false;
       finished := false;
       repeat
       repeat
-        BlocksList := TList.Create;
+        BlocksList := TList<TPCOperationsComp>.Create;
         try
         try
           finished := NOT Do_GetOperationsBlock(Bank,start,start + 50,30000,false,BlocksList);
           finished := NOT Do_GetOperationsBlock(Bank,start,start + 50,30000,false,BlocksList);
           i := 0;
           i := 0;
@@ -1944,7 +1933,7 @@ Const CT_LogSender = 'GetNewBlockChainFromClient';
     newBlock : TBlockAccount;
     newBlock : TBlockAccount;
     opComp : TPCOperationsComp;
     opComp : TPCOperationsComp;
     errors : String;
     errors : String;
-    blocksList : TList;
+    blocksList : TList<TPCOperationsComp>;
     i : Integer;
     i : Integer;
     rid : Cardinal;
     rid : Cardinal;
     download_new_safebox : Boolean;
     download_new_safebox : Boolean;
@@ -1975,7 +1964,7 @@ Const CT_LogSender = 'GetNewBlockChainFromClient';
               TLog.NewLog(ltInfo,ClassName,'Received new safebox!');
               TLog.NewLog(ltInfo,ClassName,'Received new safebox!');
               newTmpBank.Storage.SaveBank(True); // Saving bank
               newTmpBank.Storage.SaveBank(True); // Saving bank
               // Receive at least 1 new block
               // Receive at least 1 new block
-              blocksList := TList.Create;
+              blocksList := TList<TPCOperationsComp>.Create;
               try
               try
                 if Not Do_GetOperationsBlock(newTmpBank,safebox_last_operation_block.block,safebox_last_operation_block.block+10,20000,False,blocksList) then begin
                 if Not Do_GetOperationsBlock(newTmpBank,safebox_last_operation_block.block,safebox_last_operation_block.block+10,20000,False,blocksList) then begin
                   TLog.NewLog(ltError,ClassName,Format('Cannot receive at least 1 new block:%d',[safebox_last_operation_block.block]));
                   TLog.NewLog(ltError,ClassName,Format('Cannot receive at least 1 new block:%d',[safebox_last_operation_block.block]));
@@ -2207,14 +2196,14 @@ begin
 end;
 end;
 
 
 procedure TNetData.Notification(AComponent: TComponent; Operation: TOperation);
 procedure TNetData.Notification(AComponent: TComponent; Operation: TOperation);
-Var l : TList;
+Var l : TList<TNetConnection>;
 begin
 begin
   inherited;
   inherited;
-  if Operation=OpRemove then begin
+  if (Operation=OpRemove) and Assigned(AComponent) and (AComponent is TNetConnection) then begin
     if not (csDestroying in ComponentState) then begin
     if not (csDestroying in ComponentState) then begin
       l := FNetConnections.LockList;
       l := FNetConnections.LockList;
       try
       try
-        if l.Remove(AComponent)>=0 then begin
+        if l.Remove(TNetConnection(AComponent))>=0 then begin
           NotifyNetConnectionUpdated;
           NotifyNetConnectionUpdated;
         end;
         end;
       finally
       finally
@@ -2285,7 +2274,7 @@ end;
 function TNetData.PendingRequest(Sender: TNetConnection; var requests_data : String): Integer;
 function TNetData.PendingRequest(Sender: TNetConnection; var requests_data : String): Integer;
 Var P : PNetRequestRegistered;
 Var P : PNetRequestRegistered;
   i : Integer;
   i : Integer;
-  l : TList;
+  l : TList<Pointer>;
 begin
 begin
   requests_data := '';
   requests_data := '';
   l := FRegisteredRequests.LockList;
   l := FRegisteredRequests.LockList;
@@ -2306,7 +2295,7 @@ end;
 
 
 procedure TNetData.RegisterRequest(Sender: TNetConnection; operation: Word; request_id: Cardinal);
 procedure TNetData.RegisterRequest(Sender: TNetConnection; operation: Word; request_id: Cardinal);
 Var P : PNetRequestRegistered;
 Var P : PNetRequestRegistered;
-  l : TList;
+  l : TList<Pointer>;
 begin
 begin
   l := FRegisteredRequests.LockList;
   l := FRegisteredRequests.LockList;
   Try
   Try
@@ -2333,7 +2322,7 @@ end;
 function TNetData.UnRegisterRequest(Sender: TNetConnection; operation: Word; request_id: Cardinal): Boolean;
 function TNetData.UnRegisterRequest(Sender: TNetConnection; operation: Word; request_id: Cardinal): Boolean;
 Var P : PNetRequestRegistered;
 Var P : PNetRequestRegistered;
   i : Integer;
   i : Integer;
-  l : TList;
+  l : TList<Pointer>;
 begin
 begin
   Result := false;
   Result := false;
   l := FRegisteredRequests.LockList;
   l := FRegisteredRequests.LockList;
@@ -2486,7 +2475,6 @@ end;
 
 
 function TNetConnection.ConnectTo(ServerIP: String; ServerPort: Word) : Boolean;
 function TNetConnection.ConnectTo(ServerIP: String; ServerPort: Word) : Boolean;
 Var nsa : TNodeServerAddress;
 Var nsa : TNodeServerAddress;
-  lns : TList;
   i : Integer;
   i : Integer;
 begin
 begin
   If FIsConnecting then Exit;
   If FIsConnecting then Exit;
@@ -2732,7 +2720,7 @@ procedure TNetConnection.DoProcess_GetBlockchainOperations_Request(HeaderData: T
       op_size : 4 bytes
       op_size : 4 bytes
       op_data : (op_size) bytes
       op_data : (op_size) bytes
   }
   }
-  function GetBlock(bufferOperationsBlock : TList; nBlock : Integer) : TPCOperationsComp;
+  function GetBlock(bufferOperationsBlock : TList<TPCOperationsComp>; nBlock : Integer) : TPCOperationsComp;
   var i : Integer;
   var i : Integer;
   begin
   begin
     // Search at buffer:
     // Search at buffer:
@@ -2748,7 +2736,7 @@ procedure TNetConnection.DoProcess_GetBlockchainOperations_Request(HeaderData: T
 Var input_operations_count, cBlock, cBlockOpIndex, c : Cardinal;
 Var input_operations_count, cBlock, cBlockOpIndex, c : Cardinal;
   block_op_ref : UInt64;
   block_op_ref : UInt64;
   i : Integer;
   i : Integer;
-  bufferOperationsBlock : TList;
+  bufferOperationsBlock : TList<TPCOperationsComp>;
   opc : TPCOperationsComp;
   opc : TPCOperationsComp;
   outputBuffer : TStream;
   outputBuffer : TStream;
   opindexdata : TStream;
   opindexdata : TStream;
@@ -2771,7 +2759,7 @@ begin
       Exit;
       Exit;
     end;
     end;
     outputBuffer.Write(input_operations_count,SizeOf(input_operations_count));
     outputBuffer.Write(input_operations_count,SizeOf(input_operations_count));
-    bufferOperationsBlock := TList.Create;
+    bufferOperationsBlock := TList<TPCOperationsComp>.Create;
     opindexdata := TStream.Create;
     opindexdata := TStream.Create;
     Try
     Try
       for i := 1 to input_operations_count do begin
       for i := 1 to input_operations_count do begin
@@ -3508,9 +3496,9 @@ Begin
       TLog.NewLog(ltDebug,ClassName,'Corrected timestamp for node ('+ClientRemoteAddr+') old offset: '+IntToStr(lastTimestampDiff)+' current offset '+IntToStr(FTimestampDiff) );
       TLog.NewLog(ltDebug,ClassName,'Corrected timestamp for node ('+ClientRemoteAddr+') old offset: '+IntToStr(lastTimestampDiff)+' current offset '+IntToStr(FTimestampDiff) );
     end;
     end;
 
 
-    if (connection_has_a_server>0) And (Not SameText(Client.RemoteHost,'localhost')) And (Not SameText('127.',Copy(Client.RemoteHost,1,4)))
-      And (Not SameText('192.168.',Copy(Client.RemoteHost,1,8)))
-      And (Not SameText('10.',Copy(Client.RemoteHost,1,3)))
+    if (connection_has_a_server>0) And (Not SameText(Client.RemoteHost,'localhost')) And (Not SameText('127.',Client.RemoteHost.Substring(0,4)))
+      And (Not SameText('192.168.',Client.RemoteHost.Substring(0,8)))
+      And (Not SameText('10.',Client.RemoteHost.Substring(0,3)))
       And (Not TAccountComp.EqualAccountKeys(FClientPublicKey,TNetData.NetData.FNodePrivateKey.PublicKey)) then begin
       And (Not TAccountComp.EqualAccountKeys(FClientPublicKey,TNetData.NetData.FNodePrivateKey.PublicKey)) then begin
       nsa := CT_TNodeServerAddress_NUL;
       nsa := CT_TNodeServerAddress_NUL;
       nsa.ip := Client.RemoteHost;
       nsa.ip := Client.RemoteHost;
@@ -4623,7 +4611,7 @@ end;
 { TThreadCheckConnections }
 { TThreadCheckConnections }
 
 
 procedure TThreadCheckConnections.BCExecute;
 procedure TThreadCheckConnections.BCExecute;
-Var l : TList;
+Var l : TList<TNetConnection>;
   i, nactive,ndeleted,nserverclients : Integer;
   i, nactive,ndeleted,nserverclients : Integer;
   netconn : TNetConnection;
   netconn : TNetConnection;
   netserverclientstop : TNetServerClient;
   netserverclientstop : TNetServerClient;
@@ -4705,14 +4693,14 @@ end;
 procedure TThreadGetNewBlockChainFromClient.BCExecute;
 procedure TThreadGetNewBlockChainFromClient.BCExecute;
 Var i,j : Integer;
 Var i,j : Integer;
   maxWork : UInt64;
   maxWork : UInt64;
-  candidates : TList;
+  candidates : TList<TNetConnection>;
   lop : TOperationBlock;
   lop : TOperationBlock;
   nc : TNetConnection;
   nc : TNetConnection;
 begin
 begin
   if Not TNode.Node.UpdateBlockchain then Exit;
   if Not TNode.Node.UpdateBlockchain then Exit;
 
 
   // Search better candidates:
   // Search better candidates:
-  candidates := TList.Create;
+  candidates := TList<TNetConnection>.Create;
   try
   try
     lop := CT_OperationBlock_NUL;
     lop := CT_OperationBlock_NUL;
     TNetData.NetData.FMaxRemoteOperationBlock := CT_OperationBlock_NUL;
     TNetData.NetData.FMaxRemoteOperationBlock := CT_OperationBlock_NUL;
@@ -4836,10 +4824,10 @@ end;
 { TNetClientsDestroyThread }
 { TNetClientsDestroyThread }
 
 
 procedure TNetClientsDestroyThread.BCExecute;
 procedure TNetClientsDestroyThread.BCExecute;
-Var l,l_to_del : TList;
+Var l,l_to_del : TList<TNetConnection>;
   i : Integer;
   i : Integer;
 begin
 begin
-  l_to_del := TList.Create;
+  l_to_del := TList<TNetConnection>.Create;
   Try
   Try
     while not Terminated do begin
     while not Terminated do begin
       l_to_del.Clear;
       l_to_del.Clear;
@@ -4907,7 +4895,7 @@ Type TNetworkAdjustedTimeReg = Record
    PNetworkAdjustedTimeReg = ^TNetworkAdjustedTimeReg;
    PNetworkAdjustedTimeReg = ^TNetworkAdjustedTimeReg;
 
 
 procedure TNetworkAdjustedTime.AddNewIp(const clientIp: String; clientTimestamp : Cardinal);
 procedure TNetworkAdjustedTime.AddNewIp(const clientIp: String; clientTimestamp : Cardinal);
-Var l : TList;
+Var l : TList<Pointer>;
   i : Integer;
   i : Integer;
   P : PNetworkAdjustedTimeReg;
   P : PNetworkAdjustedTimeReg;
 begin
 begin
@@ -4934,7 +4922,7 @@ end;
 
 
 constructor TNetworkAdjustedTime.Create;
 constructor TNetworkAdjustedTime.Create;
 begin
 begin
-  FTimesList := TPCThreadList.Create('TNetworkAdjustedTime_TimesList');
+  FTimesList := TPCThreadList<Pointer>.Create('TNetworkAdjustedTime_TimesList');
   FTimeOffset := 0;
   FTimeOffset := 0;
   FTotalCounter := 0;
   FTotalCounter := 0;
 end;
 end;
@@ -4942,7 +4930,7 @@ end;
 destructor TNetworkAdjustedTime.Destroy;
 destructor TNetworkAdjustedTime.Destroy;
 Var P : PNetworkAdjustedTimeReg;
 Var P : PNetworkAdjustedTimeReg;
   i : Integer;
   i : Integer;
-  l : TList;
+  l : TList<Pointer>;
 begin
 begin
   l := FTimesList.LockList;
   l := FTimesList.LockList;
   try
   try
@@ -4964,7 +4952,7 @@ begin
 end;
 end;
 
 
 function TNetworkAdjustedTime.GetMaxAllowedTimestampForNewBlock: Cardinal;
 function TNetworkAdjustedTime.GetMaxAllowedTimestampForNewBlock: Cardinal;
-var l : TList;
+var l : TList<Pointer>;
 begin
 begin
   l := FTimesList.LockList;
   l := FTimesList.LockList;
   try
   try
@@ -4974,7 +4962,7 @@ begin
   end;
   end;
 end;
 end;
 
 
-function TNetworkAdjustedTime.IndexOfClientIp(list: TList; const clientIp: String): Integer;
+function TNetworkAdjustedTime.IndexOfClientIp(list: TList<Pointer>; const clientIp: String): Integer;
 begin
 begin
   for Result := 0 to list.Count - 1 do begin
   for Result := 0 to list.Count - 1 do begin
     if SameStr(PNetworkAdjustedTimeReg(list[result])^.clientIp,clientIp) then exit;
     if SameStr(PNetworkAdjustedTimeReg(list[result])^.clientIp,clientIp) then exit;
@@ -4983,7 +4971,7 @@ begin
 end;
 end;
 
 
 procedure TNetworkAdjustedTime.RemoveIp(const clientIp: String);
 procedure TNetworkAdjustedTime.RemoveIp(const clientIp: String);
-Var l : TList;
+Var l : TList<Pointer>;
   i : Integer;
   i : Integer;
   P : PNetworkAdjustedTimeReg;
   P : PNetworkAdjustedTimeReg;
 begin
 begin
@@ -5008,13 +4996,8 @@ begin
   end;
   end;
 end;
 end;
 
 
-function SortPNetworkAdjustedTimeReg(p1, p2: pointer): integer;
-begin
-  Result := PNetworkAdjustedTimeReg(p1)^.timeOffset - PNetworkAdjustedTimeReg(p2)^.timeOffset;
-end;
-
 procedure TNetworkAdjustedTime.UpdateIp(const clientIp: String; clientTimestamp: Cardinal);
 procedure TNetworkAdjustedTime.UpdateIp(const clientIp: String; clientTimestamp: Cardinal);
-Var l : TList;
+Var l : TList<Pointer>;
   i : Integer;
   i : Integer;
   P : PNetworkAdjustedTimeReg;
   P : PNetworkAdjustedTimeReg;
   lastOffset : Integer;
   lastOffset : Integer;
@@ -5039,13 +5022,47 @@ begin
   end;
   end;
 end;
 end;
 
 
-procedure TNetworkAdjustedTime.UpdateMedian(list : TList);
+{$IFDEF FPC}
+type
+  TPNetworkAdjustedTimeReg = class(TInterfacedObject, IComparer<Pointer>)
+  public
+    function Compare(constref ALeft, ARight: Pointer): Integer;
+  end;
+
+{ TPNetworkAdjustedTimeReg }
+
+function TPNetworkAdjustedTimeReg.Compare(constref ALeft, ARight: Pointer): Integer;
+begin
+  Result := PNetworkAdjustedTimeReg(ALeft)^.timeOffset - PNetworkAdjustedTimeReg(ARight)^.timeOffset;
+end;
+{$ENDIF}
+
+procedure TNetworkAdjustedTime.UpdateMedian(list : TList<Pointer>);
 Var last : Integer;
 Var last : Integer;
   i : Integer;
   i : Integer;
   s : String;
   s : String;
+{$IFNDEF FPC}
+  LComparison : TComparison<Pointer>;
+{$ELSE}
+  LComparer : TPNetworkAdjustedTimeReg;
+{$ENDIF}
 begin
 begin
   last := FTimeOffset;
   last := FTimeOffset;
-  list.Sort(SortPNetworkAdjustedTimeReg);
+  {$IFDEF FPC}
+  LComparer := TPNetworkAdjustedTimeReg.Create;
+  try
+    list.Sort(LComparer);
+  finally
+    LComparer.Free;
+  end;
+  {$ELSE}
+  LComparison :=
+  function(const Left, Right: Pointer): Integer
+  begin
+    Result := PNetworkAdjustedTimeReg(Left)^.timeOffset - PNetworkAdjustedTimeReg(Right)^.timeOffset;
+  end;
+  List.Sort(TComparer<Pointer>.Construct(LComparison));
+  {$ENDIF}
   if list.Count<CT_MinNodesToCalcNAT then begin
   if list.Count<CT_MinNodesToCalcNAT then begin
     FTimeOffset := 0;
     FTimeOffset := 0;
   end else if ((list.Count MOD 2)=0) then begin
   end else if ((list.Count MOD 2)=0) then begin

+ 11 - 9
src/core/UNode.pas

@@ -34,7 +34,9 @@ unit UNode;
 interface
 interface
 
 
 uses
 uses
-  Classes, SysUtils, UBlockChain, UNetProtocol, UAccounts, UCrypto, UThread, SyncObjs, ULog, UBaseTypes, UPCOrderedLists;
+  Classes, SysUtils,
+  {$IFNDEF FPC}System.Generics.Collections{$ELSE}Generics.Collections{$ENDIF},
+  UBlockChain, UNetProtocol, UAccounts, UCrypto, UThread, SyncObjs, ULog, UBaseTypes, UPCOrderedLists;
 
 
 {$I config.inc}
 {$I config.inc}
 
 
@@ -44,12 +46,14 @@ Type
 
 
   TSearchOperationResult = (found, invalid_params, blockchain_block_not_found);
   TSearchOperationResult = (found, invalid_params, blockchain_block_not_found);
 
 
+  TNodeNotifyEvents = Class;
+
   TNode = Class(TComponent)
   TNode = Class(TComponent)
   private
   private
     FNodeLog : TLog;
     FNodeLog : TLog;
     FLockNodeOperations : TPCCriticalSection;
     FLockNodeOperations : TPCCriticalSection;
     FOperationSequenceLock : TPCCriticalSection;
     FOperationSequenceLock : TPCCriticalSection;
-    FNotifyList : TList;
+    FNotifyList : TList<TNodeNotifyEvents>;
     FBank : TPCBank;
     FBank : TPCBank;
     FOperations : TPCOperationsComp;
     FOperations : TPCOperationsComp;
     FNetServer : TNetServer;
     FNetServer : TNetServer;
@@ -111,8 +115,6 @@ Type
     class function NodeVersion : String;
     class function NodeVersion : String;
   End;
   End;
 
 
-  TNodeNotifyEvents = Class;
-
   TThreadSafeNodeNotifyEvent = Class(TPCThread)
   TThreadSafeNodeNotifyEvent = Class(TPCThread)
     FNodeNotifyEvents : TNodeNotifyEvents;
     FNodeNotifyEvents : TNodeNotifyEvents;
     FNotifyBlocksChanged : Boolean;
     FNotifyBlocksChanged : Boolean;
@@ -145,7 +147,7 @@ Type
   private
   private
     FNode: TNode;
     FNode: TNode;
     FOnKeyActivity: TNotifyEvent;
     FOnKeyActivity: TNotifyEvent;
-    FPendingNotificationsList : TPCThreadList;
+    FPendingNotificationsList : TPCThreadList<Pointer>;
     FThreadSafeNodeNotifyEvent : TThreadSafeNodeNotifyEvent;
     FThreadSafeNodeNotifyEvent : TThreadSafeNodeNotifyEvent;
     FOnBlocksChanged: TNotifyEvent;
     FOnBlocksChanged: TNotifyEvent;
     FOnOperationsChanged: TNotifyEvent;
     FOnOperationsChanged: TNotifyEvent;
@@ -568,7 +570,7 @@ begin
   FNetServer := TNetServer.Create;
   FNetServer := TNetServer.Create;
   FOperations := TPCOperationsComp.Create(Nil);
   FOperations := TPCOperationsComp.Create(Nil);
   FOperations.bank := FBank;
   FOperations.bank := FBank;
-  FNotifyList := TList.Create;
+  FNotifyList := TList<TNodeNotifyEvents>.Create;
   {$IFDEF BufferOfFutureOperations}
   {$IFDEF BufferOfFutureOperations}
   FBufferAuxWaitingOperations := TOperationsHashTree.Create;
   FBufferAuxWaitingOperations := TOperationsHashTree.Create;
   {$ENDIF}
   {$ENDIF}
@@ -815,7 +817,7 @@ procedure TNode.GetStoredOperationsFromAccount(const OperationsResume: TOperatio
   var opc : TPCOperationsComp;
   var opc : TPCOperationsComp;
     op : TPCOperation;
     op : TPCOperation;
     OPR : TOperationResume;
     OPR : TOperationResume;
-    l : TList;
+    l : TList<Cardinal>;
     i : Integer;
     i : Integer;
     last_block_number : Integer;
     last_block_number : Integer;
     found_in_block : Boolean;
     found_in_block : Boolean;
@@ -825,7 +827,7 @@ procedure TNode.GetStoredOperationsFromAccount(const OperationsResume: TOperatio
     if (act_depth<=0) then exit;
     if (act_depth<=0) then exit;
     opc := TPCOperationsComp.Create(Nil);
     opc := TPCOperationsComp.Create(Nil);
     Try
     Try
-      l := TList.Create;
+      l := TList<Cardinal>.Create;
       try
       try
         last_block_number := block_number+1;
         last_block_number := block_number+1;
         while (last_block_number>block_number) And (act_depth>0)
         while (last_block_number>block_number) And (act_depth>0)
@@ -1225,7 +1227,7 @@ begin
   FWatchKeys := Nil;
   FWatchKeys := Nil;
   FOnKeyActivity:=Nil;
   FOnKeyActivity:=Nil;
   FMessages := TStringList.Create;
   FMessages := TStringList.Create;
-  FPendingNotificationsList := TPCThreadList.Create('TNodeNotifyEvents_PendingNotificationsList');
+  FPendingNotificationsList := TPCThreadList<Pointer>.Create('TNodeNotifyEvents_PendingNotificationsList');
   FThreadSafeNodeNotifyEvent := TThreadSafeNodeNotifyEvent.Create(Self);
   FThreadSafeNodeNotifyEvent := TThreadSafeNodeNotifyEvent.Create(Self);
   Node := _Node;
   Node := _Node;
 end;
 end;

+ 28 - 26
src/core/UOpTransaction.pas

@@ -22,7 +22,9 @@ unit UOpTransaction;
 
 
 interface
 interface
 
 
-Uses UCrypto, UBlockChain, Classes, UAccounts, UBaseTypes, UPCDataTypes;
+Uses UCrypto, UBlockChain, Classes, UAccounts, UBaseTypes,
+  {$IFNDEF FPC}System.Generics.Collections{$ELSE}Generics.Collections{$ENDIF},
+  UPCDataTypes;
 
 
 Type
 Type
   // Operations Type
   // Operations Type
@@ -80,7 +82,7 @@ Type
   public
   public
     function GetBufferForOpHash(UseProtocolV2 : Boolean): TRawBytes; override;
     function GetBufferForOpHash(UseProtocolV2 : Boolean): TRawBytes; override;
     function DoOperation(AccountPreviousUpdatedBlock : TAccountPreviousBlockInfo; AccountTransaction : TPCSafeBoxTransaction; var errors : String) : Boolean; override;
     function DoOperation(AccountPreviousUpdatedBlock : TAccountPreviousBlockInfo; AccountTransaction : TPCSafeBoxTransaction; var errors : String) : Boolean; override;
-    procedure AffectedAccounts(list : TList); override;
+    procedure AffectedAccounts(list : TList<Cardinal>); override;
     //
     //
     class function OpType : Byte; override;
     class function OpType : Byte; override;
     function OperationAmount : Int64; override;
     function OperationAmount : Int64; override;
@@ -119,7 +121,7 @@ Type
     function SignerAccount : Cardinal; override;
     function SignerAccount : Cardinal; override;
     function DestinationAccount : Int64; override;
     function DestinationAccount : Int64; override;
     function N_Operation : Cardinal; override;
     function N_Operation : Cardinal; override;
-    procedure AffectedAccounts(list : TList); override;
+    procedure AffectedAccounts(list : TList<Cardinal>); override;
     function OperationAmountByAccount(account : Cardinal) : Int64; override;
     function OperationAmountByAccount(account : Cardinal) : Int64; override;
     Constructor Create(current_protocol : Word; account_signer, n_operation, account_target: Cardinal; key:TECPrivateKey; new_account_key : TAccountKey; fee: UInt64; payload: TRawBytes);
     Constructor Create(current_protocol : Word; account_signer, n_operation, account_target: Cardinal; key:TECPrivateKey; new_account_key : TAccountKey; fee: UInt64; payload: TRawBytes);
     Property Data : TOpChangeKeyData read FData;
     Property Data : TOpChangeKeyData read FData;
@@ -156,7 +158,7 @@ Type
     function SignerAccount : Cardinal; override;
     function SignerAccount : Cardinal; override;
     function N_Operation : Cardinal; override;
     function N_Operation : Cardinal; override;
     function OperationAmountByAccount(account : Cardinal) : Int64; override;
     function OperationAmountByAccount(account : Cardinal) : Int64; override;
-    procedure AffectedAccounts(list : TList); override;
+    procedure AffectedAccounts(list : TList<Cardinal>); override;
     Constructor Create(account_number, n_operation: Cardinal; fee: UInt64);
     Constructor Create(account_number, n_operation: Cardinal; fee: UInt64);
     Property Data : TOpRecoverFoundsData read FData;
     Property Data : TOpRecoverFoundsData read FData;
     Function toString : String; Override;
     Function toString : String; Override;
@@ -225,7 +227,7 @@ Type
     function DestinationAccount : Int64; override;
     function DestinationAccount : Int64; override;
     function SellerAccount : Int64; override;
     function SellerAccount : Int64; override;
     function N_Operation : Cardinal; override;
     function N_Operation : Cardinal; override;
-    procedure AffectedAccounts(list : TList); override;
+    procedure AffectedAccounts(list : TList<Cardinal>); override;
     function OperationAmountByAccount(account : Cardinal) : Int64; override;
     function OperationAmountByAccount(account : Cardinal) : Int64; override;
     Property Data : TOpListAccountData read FData;
     Property Data : TOpListAccountData read FData;
     Function toString : String; Override;
     Function toString : String; Override;
@@ -277,7 +279,7 @@ Type
     function SignerAccount : Cardinal; override;
     function SignerAccount : Cardinal; override;
     function DestinationAccount : Int64; override;
     function DestinationAccount : Int64; override;
     function N_Operation : Cardinal; override;
     function N_Operation : Cardinal; override;
-    procedure AffectedAccounts(list : TList); override;
+    procedure AffectedAccounts(list : TList<Cardinal>); override;
     function OperationAmountByAccount(account : Cardinal) : Int64; override;
     function OperationAmountByAccount(account : Cardinal) : Int64; override;
     Constructor CreateChangeAccountInfo(current_protocol : word;
     Constructor CreateChangeAccountInfo(current_protocol : word;
       account_signer, n_operation, account_target: Cardinal; key:TECPrivateKey;
       account_signer, n_operation, account_target: Cardinal; key:TECPrivateKey;
@@ -325,7 +327,7 @@ Type
     function SignerAccount : Cardinal; override;
     function SignerAccount : Cardinal; override;
     function DestinationAccount : Int64; override;
     function DestinationAccount : Int64; override;
     function N_Operation : Cardinal; override;
     function N_Operation : Cardinal; override;
-    procedure AffectedAccounts(list : TList); override;
+    procedure AffectedAccounts(list : TList<Cardinal>); override;
     function OperationAmountByAccount(account : Cardinal) : Int64; override;
     function OperationAmountByAccount(account : Cardinal) : Int64; override;
     Constructor CreateOpData(
     Constructor CreateOpData(
       account_signer, account_sender, account_target : Cardinal; signer_key:TECPrivateKey;
       account_signer, account_sender, account_target : Cardinal; signer_key:TECPrivateKey;
@@ -596,10 +598,10 @@ begin
   Result := FData.n_operation;
   Result := FData.n_operation;
 end;
 end;
 
 
-procedure TOpChangeAccountInfo.AffectedAccounts(list: TList);
+procedure TOpChangeAccountInfo.AffectedAccounts(list: TList<Cardinal>);
 begin
 begin
-  list.Add(TObject(FData.account_signer));
-  if (FData.account_target<>FData.account_signer) then list.Add(TObject(FData.account_target));
+  list.Add(FData.account_signer);
+  if (FData.account_target<>FData.account_signer) then list.Add(FData.account_target);
 end;
 end;
 
 
 function TOpChangeAccountInfo.OperationAmountByAccount(account: Cardinal): Int64;
 function TOpChangeAccountInfo.OperationAmountByAccount(account: Cardinal): Int64;
@@ -702,12 +704,12 @@ end;
 
 
 { TOpTransaction }
 { TOpTransaction }
 
 
-procedure TOpTransaction.AffectedAccounts(list: TList);
+procedure TOpTransaction.AffectedAccounts(list: TList<Cardinal>);
 begin
 begin
-  list.Add(TObject(FData.sender));
-  list.Add(TObject(FData.target));
+  list.Add(FData.sender);
+  list.Add(FData.target);
   if (FData.opTransactionStyle in [transaction_with_auto_buy_account, buy_account]) then begin
   if (FData.opTransactionStyle in [transaction_with_auto_buy_account, buy_account]) then begin
-    list.Add(TObject(FData.SellerAccount));
+    list.Add(FData.SellerAccount);
   end;
   end;
 end;
 end;
 
 
@@ -1154,10 +1156,10 @@ end;
 
 
 { TOpChangeKey }
 { TOpChangeKey }
 
 
-procedure TOpChangeKey.AffectedAccounts(list: TList);
+procedure TOpChangeKey.AffectedAccounts(list: TList<Cardinal>);
 begin
 begin
-  list.Add(TObject(FData.account_signer));
-  if (FData.account_target<>FData.account_signer) then list.Add(TObject(FData.account_target));
+  list.Add(FData.account_signer);
+  if (FData.account_target<>FData.account_signer) then list.Add(FData.account_target);
 end;
 end;
 
 
 function TOpChangeKey.OperationAmountByAccount(account: Cardinal): Int64;
 function TOpChangeKey.OperationAmountByAccount(account: Cardinal): Int64;
@@ -1489,9 +1491,9 @@ end;
 
 
 { TOpRecoverFounds }
 { TOpRecoverFounds }
 
 
-procedure TOpRecoverFounds.AffectedAccounts(list: TList);
+procedure TOpRecoverFounds.AffectedAccounts(list: TList<Cardinal>);
 begin
 begin
-  list.Add(TObject(FData.account));
+  list.Add(FData.account);
 end;
 end;
 
 
 constructor TOpRecoverFounds.Create(account_number, n_operation : Cardinal; fee: UInt64);
 constructor TOpRecoverFounds.Create(account_number, n_operation : Cardinal; fee: UInt64);
@@ -1640,11 +1642,11 @@ end;
 
 
 { TOpListAccount }
 { TOpListAccount }
 
 
-procedure TOpListAccount.AffectedAccounts(list: TList);
+procedure TOpListAccount.AffectedAccounts(list: TList<Cardinal>);
 begin
 begin
-  list.Add(TObject(FData.account_signer));
+  list.Add(FData.account_signer);
   if FData.account_signer<>FData.account_target then
   if FData.account_signer<>FData.account_target then
-    list.Add(TObject(FData.account_target));
+    list.Add(FData.account_target);
 end;
 end;
 
 
 function TOpListAccount.OperationAmountByAccount(account: Cardinal): Int64;
 function TOpListAccount.OperationAmountByAccount(account: Cardinal): Int64;
@@ -2344,14 +2346,14 @@ begin
   Result := FData.n_operation;
   Result := FData.n_operation;
 end;
 end;
 
 
-procedure TOpData.AffectedAccounts(list: TList);
+procedure TOpData.AffectedAccounts(list: TList<Cardinal>);
 begin
 begin
-  list.Add(TObject(FData.account_signer));
+  list.Add(FData.account_signer);
   if (FData.account_signer<>FData.account_sender) then begin
   if (FData.account_signer<>FData.account_sender) then begin
-    list.Add(TObject(FData.account_sender));
+    list.Add(FData.account_sender);
   end;
   end;
   if (FData.account_signer<>FData.account_target) And (FData.account_sender<>FData.account_target) then begin
   if (FData.account_signer<>FData.account_target) And (FData.account_sender<>FData.account_target) then begin
-    list.Add(TObject(FData.account_target));
+    list.Add(FData.account_target);
   end;
   end;
 end;
 end;
 
 

+ 1 - 1
src/core/UPCOpenSSLSignature.pas

@@ -38,7 +38,7 @@ interface
   ERROR: Use_OpenSSL is not defined!
   ERROR: Use_OpenSSL is not defined!
 {$ENDIF}
 {$ENDIF}
 
 
-Uses SysUtils, UBaseTypes,
+Uses SysUtils,
   UOpenSSL,
   UOpenSSL,
   UPCDataTypes;
   UPCDataTypes;
 
 

+ 9 - 8
src/core/UPCOrderedLists.pas

@@ -23,7 +23,8 @@ unit UPCOrderedLists;
 interface
 interface
 
 
 uses
 uses
-  Classes, SysUtils, UBaseTypes;
+  Classes, SysUtils, UBaseTypes,
+  {$IFNDEF FPC}System.Generics.Collections{$ELSE}Generics.Collections{$ENDIF};
 
 
 Type
 Type
   TCardinalsArray = Array of Cardinal;
   TCardinalsArray = Array of Cardinal;
@@ -34,7 +35,7 @@ Type
 
 
   TOrderedCardinalList = Class
   TOrderedCardinalList = Class
   private
   private
-    FOrderedList : TList;
+    FOrderedList : TList<Cardinal>;
     FDisabledsCount : Integer;
     FDisabledsCount : Integer;
     FModifiedWhileDisabled : Boolean;
     FModifiedWhileDisabled : Boolean;
     FOnListChanged: TNotifyEvent;
     FOnListChanged: TNotifyEvent;
@@ -62,7 +63,7 @@ Type
 
 
   TOrderedCardinalListWithRaw = Class
   TOrderedCardinalListWithRaw = Class
   private
   private
-    FList : TList;
+    FList : TList<Pointer>;
     Function Find(value : Cardinal; var Index: Integer): Boolean;
     Function Find(value : Cardinal; var Index: Integer): Boolean;
   public
   public
     Constructor Create;
     Constructor Create;
@@ -83,7 +84,7 @@ Type
 
 
   TOrderedRawList = Class
   TOrderedRawList = Class
   private
   private
-    FList : TList;
+    FList : TList<Pointer>;
   public
   public
     Constructor Create;
     Constructor Create;
     Destructor Destroy; Override;
     Destructor Destroy; Override;
@@ -120,7 +121,7 @@ begin
         FOrderedList.Capacity:=nc;
         FOrderedList.Capacity:=nc;
       end;
       end;
     end;
     end;
-    FOrderedList.Insert(Result,TObject(Value));
+    FOrderedList.Insert(Result,(Value));
     NotifyChanged;
     NotifyChanged;
   end;
   end;
 end;
 end;
@@ -154,7 +155,7 @@ end;
 
 
 constructor TOrderedCardinalList.Create;
 constructor TOrderedCardinalList.Create;
 begin
 begin
-  FOrderedList := TList.Create;
+  FOrderedList := TList<Cardinal>.Create;
   FDisabledsCount := 0;
   FDisabledsCount := 0;
   FModifiedWhileDisabled := false;
   FModifiedWhileDisabled := false;
 end;
 end;
@@ -291,7 +292,7 @@ end;
 
 
 constructor TOrderedRawList.Create;
 constructor TOrderedRawList.Create;
 begin
 begin
-  FList := TList.Create;
+  FList := TList<Pointer>.Create;
 end;
 end;
 
 
 procedure TOrderedRawList.Delete(index: Integer);
 procedure TOrderedRawList.Delete(index: Integer);
@@ -408,7 +409,7 @@ end;
 
 
 constructor TOrderedCardinalListWithRaw.Create;
 constructor TOrderedCardinalListWithRaw.Create;
 begin
 begin
-  FList := TList.Create;
+  FList := TList<Pointer>.Create;
 end;
 end;
 
 
 destructor TOrderedCardinalListWithRaw.Destroy;
 destructor TOrderedCardinalListWithRaw.Destroy;

+ 1 - 1
src/core/UPipeline.pas

@@ -20,7 +20,7 @@ unit UPipeline;
 interface
 interface
 
 
 uses
 uses
-  Generics.Collections, Classes, SyncObjs, SysUtils, UThread;
+  {$IFNDEF FPC}System.Generics.Collections{$ELSE}Generics.Collections{$ENDIF}, Classes, SyncObjs, SysUtils, UThread;
 
 
 Type
 Type
   { TPipelineQueue }
   { TPipelineQueue }

+ 29 - 25
src/core/UPoolMinerThreads.pas

@@ -25,7 +25,8 @@ interface
 {$I config.inc}
 {$I config.inc}
 
 
 uses
 uses
-  Classes, SysUtils, syncobjs, UThread, UPoolMining, UAccounts, UCrypto, ULog, UBlockChain, USha256, URandomHash, UBaseTypes, UCommon;
+  Classes, SysUtils, syncobjs, UThread, UPoolMining, UAccounts, UCrypto, ULog, UBlockChain, USha256, URandomHash, UBaseTypes, UCommon,
+  {$IFNDEF FPC}System.Generics.Collections{$ELSE}Generics.Collections{$ENDIF};
 
 
 type
 type
   TMinerStats = Record
   TMinerStats = Record
@@ -55,7 +56,7 @@ Type
     FMinerAddName: String;
     FMinerAddName: String;
     FPoolMinerClient : TPoolMinerClient;
     FPoolMinerClient : TPoolMinerClient;
     FOnConnectionStateChanged: TNotifyEvent;
     FOnConnectionStateChanged: TNotifyEvent;
-    FDevicesList : TPCThreadList;
+    FDevicesList : TPCThreadList<TCustomMinerDeviceThread>;
     FMinerThreads: Integer;
     FMinerThreads: Integer;
     FGlobalMinerValuesForWork : TMinerValuesForWork;
     FGlobalMinerValuesForWork : TMinerValuesForWork;
     FTestingPoWLeftBits: Byte;
     FTestingPoWLeftBits: Byte;
@@ -76,7 +77,7 @@ Type
     Function CurrentMinerStats : TMinerStats;
     Function CurrentMinerStats : TMinerStats;
     Function GlobalMinerStats : TMinerStats;
     Function GlobalMinerStats : TMinerStats;
     Property GlobalMinerValuesForWork : TMinerValuesForWork read FGlobalMinerValuesForWork;
     Property GlobalMinerValuesForWork : TMinerValuesForWork read FGlobalMinerValuesForWork;
-    Function DevicesLock : TList;
+    Function DevicesLock : TList<TCustomMinerDeviceThread>;
     procedure DevicesUnlock;
     procedure DevicesUnlock;
     Property MinerAddName : String read FMinerAddName write SetMinerAddName;
     Property MinerAddName : String read FMinerAddName write SetMinerAddName;
     Property TestingPoWLeftBits : Byte read FTestingPoWLeftBits write SetTestingPoWLeftBits;
     Property TestingPoWLeftBits : Byte read FTestingPoWLeftBits write SetTestingPoWLeftBits;
@@ -93,7 +94,7 @@ Type
     FOnMinerValuesChanged: TNotifyEvent;
     FOnMinerValuesChanged: TNotifyEvent;
     FOnStateChanged: TNotifyEvent;
     FOnStateChanged: TNotifyEvent;
     FPaused: Boolean;
     FPaused: Boolean;
-    FLastStats : TPCThreadList;
+    FLastStats : TPCThreadList<Pointer>;
     FLastActiveTC : TTickCount;
     FLastActiveTC : TTickCount;
     FGlobaDeviceStats : TMinerStats;
     FGlobaDeviceStats : TMinerStats;
     FPartialDeviceStats : TMinerStats;
     FPartialDeviceStats : TMinerStats;
@@ -125,12 +126,14 @@ Type
     Property PoolMinerThread : TPoolMinerThread read FPoolMinerThread;
     Property PoolMinerThread : TPoolMinerThread read FPoolMinerThread;
   end;
   end;
 
 
+  TCPUOpenSSLMinerThread = Class;
+
   { TCPUDeviceThread }
   { TCPUDeviceThread }
 
 
   TCPUDeviceThread = Class(TCustomMinerDeviceThread)
   TCPUDeviceThread = Class(TCustomMinerDeviceThread)
   private
   private
     FCPUs: Integer;
     FCPUs: Integer;
-    FCPUsThreads : TPCThreadList;
+    FCPUsThreads : TPCThreadList<TCPUOpenSSLMinerThread>;
     FUseOpenSSLFunctions: Boolean;
     FUseOpenSSLFunctions: Boolean;
     procedure SetCPUs(AValue: Integer);
     procedure SetCPUs(AValue: Integer);
     Procedure CheckCPUs;
     Procedure CheckCPUs;
@@ -180,7 +183,7 @@ Var nID : Cardinal;
   json : TPCJSONObject;
   json : TPCJSONObject;
   i : Integer;
   i : Integer;
   ResponseMethod : String;
   ResponseMethod : String;
-  l : TList;
+  l : TList<TCustomMinerDeviceThread>;
 begin
 begin
   DebugStep:='Starting';
   DebugStep:='Starting';
   Try
   Try
@@ -238,7 +241,7 @@ begin
   FPoolMinerClient.OnConnect := OnPoolMinerClientConnectionChanged;
   FPoolMinerClient.OnConnect := OnPoolMinerClientConnectionChanged;
   FPoolMinerClient.OnDisconnect := OnPoolMinerClientConnectionChanged;
   FPoolMinerClient.OnDisconnect := OnPoolMinerClientConnectionChanged;
   FOnConnectionStateChanged := Nil;
   FOnConnectionStateChanged := Nil;
-  FDevicesList := TPCThreadList.Create('TPoolMinerThread_DevicesList');
+  FDevicesList := TPCThreadList<TCustomMinerDeviceThread>.Create('TPoolMinerThread_DevicesList');
   FMinerThreads := 0;
   FMinerThreads := 0;
   FMinerAddName:='';
   FMinerAddName:='';
   FTestingPoWLeftBits := 0;
   FTestingPoWLeftBits := 0;
@@ -247,7 +250,7 @@ begin
 end;
 end;
 
 
 function TPoolMinerThread.CurrentMinerStats: TMinerStats;
 function TPoolMinerThread.CurrentMinerStats: TMinerStats;
-Var l : TList;
+Var l : TList<TCustomMinerDeviceThread>;
   i : Integer;
   i : Integer;
   ms : TMinerStats;
   ms : TMinerStats;
 begin
 begin
@@ -270,7 +273,7 @@ end;
 
 
 destructor TPoolMinerThread.Destroy;
 destructor TPoolMinerThread.Destroy;
 Var i : Integer;
 Var i : Integer;
-  l : TList;
+  l : TList<TCustomMinerDeviceThread>;
 begin
 begin
   l := FDevicesList.LockList;
   l := FDevicesList.LockList;
   try
   try
@@ -289,7 +292,7 @@ begin
   inherited;
   inherited;
 end;
 end;
 
 
-function TPoolMinerThread.DevicesLock: TList;
+function TPoolMinerThread.DevicesLock: TList<TCustomMinerDeviceThread>;
 begin
 begin
   Result := FDevicesList.LockList;
   Result := FDevicesList.LockList;
 end;
 end;
@@ -305,7 +308,7 @@ begin
 end;
 end;
 
 
 function TPoolMinerThread.GlobalMinerStats: TMinerStats;
 function TPoolMinerThread.GlobalMinerStats: TMinerStats;
-Var l : TList;
+Var l : TList<TCustomMinerDeviceThread>;
   i : Integer;
   i : Integer;
   ms : TMinerStats;
   ms : TMinerStats;
 begin
 begin
@@ -359,7 +362,7 @@ begin
 end;
 end;
 
 
 procedure TPoolMinerThread.OnPoolMinerClientConnectionChanged(Sender: TObject);
 procedure TPoolMinerThread.OnPoolMinerClientConnectionChanged(Sender: TObject);
-Var l : TList;
+Var l : TList<TCustomMinerDeviceThread>;
   i : Integer;
   i : Integer;
 begin
 begin
   TLog.NewLog(ltInfo,ClassName,'Connection state changed. New Value:'+inttostr(Integer(FPoolMinerClient.Connected)));
   TLog.NewLog(ltInfo,ClassName,'Connection state changed. New Value:'+inttostr(Integer(FPoolMinerClient.Connected)));
@@ -375,7 +378,7 @@ begin
 end;
 end;
 
 
 procedure TPoolMinerThread.OnPoolMinerMustChangeValues(Sender: TObject);
 procedure TPoolMinerThread.OnPoolMinerMustChangeValues(Sender: TObject);
-Var l : TList;
+Var l : TList<TCustomMinerDeviceThread>;
   i,j : Integer;
   i,j : Integer;
   digest_length : Integer;
   digest_length : Integer;
   ok : Boolean;
   ok : Boolean;
@@ -436,7 +439,7 @@ begin
   FMinerValuesForWork := CT_TMinerValuesForWork_NULL;
   FMinerValuesForWork := CT_TMinerValuesForWork_NULL;
   FPartialDeviceStats := CT_TMinerStats_NULL;
   FPartialDeviceStats := CT_TMinerStats_NULL;
   FGlobaDeviceStats := CT_TMinerStats_NULL;
   FGlobaDeviceStats := CT_TMinerStats_NULL;
-  FLastStats := TPCThreadList.Create('TCustomMinerDeviceThread_LastStats');
+  FLastStats := TPCThreadList<Pointer>.Create('TCustomMinerDeviceThread_LastStats');
   FOnFoundNOnce:=Nil;
   FOnFoundNOnce:=Nil;
   FOnMinerValuesChanged:=Nil;
   FOnMinerValuesChanged:=Nil;
   FOnStateChanged:=Nil;
   FOnStateChanged:=Nil;
@@ -451,21 +454,22 @@ end;
 destructor TCustomMinerDeviceThread.Destroy;
 destructor TCustomMinerDeviceThread.Destroy;
 Var i : Integer;
 Var i : Integer;
   P : PTimeMinerStats;
   P : PTimeMinerStats;
-  l : TList;
+  ldevices : TList<TCustomMinerDeviceThread>;
+  lstats : TList<Pointer>;
 begin
 begin
-  l := FPoolMinerThread.FDevicesList.LockList;
+  ldevices := FPoolMinerThread.FDevicesList.LockList;
   try
   try
-    l.Remove(Self);
+    ldevices.Remove(Self);
   finally
   finally
     FPoolMinerThread.FDevicesList.UnlockList;
     FPoolMinerThread.FDevicesList.UnlockList;
   end;
   end;
-  l := FLastStats.LockList;
+  lstats := FLastStats.LockList;
   try
   try
-    for i:=0 to l.Count-1 do begin
-      P := l[i];
+    for i:=0 to lstats.Count-1 do begin
+      P := lstats[i];
       Dispose(P);
       Dispose(P);
     end;
     end;
-    l.clear;
+    lstats.clear;
   finally
   finally
     FLastStats.UnlockList;
     FLastStats.UnlockList;
   end;
   end;
@@ -596,7 +600,7 @@ Type TTimeMinerStats = Record
        stats : TMinerStats;
        stats : TMinerStats;
      end;
      end;
   PTimeMinerStats = ^TTimeMinerStats;
   PTimeMinerStats = ^TTimeMinerStats;
-Var l : TList;
+Var l : TList<Pointer>;
   i : Integer;
   i : Integer;
   P : PTimeMinerStats;
   P : PTimeMinerStats;
   minTC : TTickCount;
   minTC : TTickCount;
@@ -653,7 +657,7 @@ begin
 end;
 end;
 
 
 procedure TCPUDeviceThread.CheckCPUs;
 procedure TCPUDeviceThread.CheckCPUs;
-var l : TList;
+var l : TList<TCPUOpenSSLMinerThread>;
   mt : TCPUOpenSSLMinerThread;
   mt : TCPUOpenSSLMinerThread;
   needminers : Integer;
   needminers : Integer;
 begin
 begin
@@ -684,7 +688,7 @@ end;
 
 
 constructor TCPUDeviceThread.Create(PoolMinerThread: TPoolMinerThread; InitialMinerValuesForWork: TMinerValuesForWork);
 constructor TCPUDeviceThread.Create(PoolMinerThread: TPoolMinerThread; InitialMinerValuesForWork: TMinerValuesForWork);
 begin
 begin
-  FCPUsThreads := TPCThreadList.Create('TCPUDeviceThread_CPUsThreads');
+  FCPUsThreads := TPCThreadList<TCPUOpenSSLMinerThread>.Create('TCPUDeviceThread_CPUsThreads');
   FCPUs:=0;
   FCPUs:=0;
   FUseOpenSSLFunctions := True;
   FUseOpenSSLFunctions := True;
   inherited Create(PoolMinerThread, InitialMinerValuesForWork);
   inherited Create(PoolMinerThread, InitialMinerValuesForWork);
@@ -719,7 +723,7 @@ begin
 end;
 end;
 
 
 procedure TCPUDeviceThread.SetMinerValuesForWork(const Value: TMinerValuesForWork);
 procedure TCPUDeviceThread.SetMinerValuesForWork(const Value: TMinerValuesForWork);
-Var l : TList;
+Var l : TList<TCPUOpenSSLMinerThread>;
   i : Integer;
   i : Integer;
   nextmin : Cardinal;
   nextmin : Cardinal;
   npos : Integer;
   npos : Integer;

+ 17 - 16
src/core/UPoolMining.pas

@@ -31,7 +31,8 @@ Uses
   {LCLIntf, LCLType, LMessages,}
   {LCLIntf, LCLType, LMessages,}
 {$ENDIF}
 {$ENDIF}
   UTCPIP, SysUtils, UThread, SyncObjs, Classes, UJSONFunctions, UPCEncryption, UNode,
   UTCPIP, SysUtils, UThread, SyncObjs, Classes, UJSONFunctions, UPCEncryption, UNode,
-  UCrypto, UAccounts, UConst, UBlockChain, UBaseTypes;
+  UCrypto, UAccounts, UConst, UBlockChain, UBaseTypes,
+  {$IFNDEF FPC}System.Generics.Collections{$ELSE}Generics.Collections{$ENDIF};
 
 
 Const
 Const
   CT_PoolMining_Method_STATUS = 'status';
   CT_PoolMining_Method_STATUS = 'status';
@@ -65,7 +66,7 @@ Type
     FLockProcessBuffer : TPCCriticalSection;
     FLockProcessBuffer : TPCCriticalSection;
     FReceivedBuffer : TBytes;
     FReceivedBuffer : TBytes;
     FLockReceivedBuffer : TPCCriticalSection;
     FLockReceivedBuffer : TPCCriticalSection;
-    FPendingResponseMessages : TPCThreadList;
+    FPendingResponseMessages : TPCThreadList<Pointer>;
   protected
   protected
   public
   public
     Constructor Create(AOwner : TComponent); override;
     Constructor Create(AOwner : TComponent); override;
@@ -129,7 +130,7 @@ Type
     FClientsWins: Integer;
     FClientsWins: Integer;
     FClientsCount: Integer;
     FClientsCount: Integer;
     FOnMiningServerNewBlockFound: TNotifyEvent;
     FOnMiningServerNewBlockFound: TNotifyEvent;
-    FPoolJobs : TPCThreadList;
+    FPoolJobs : TPCThreadList<Pointer>;
     FPoolThread : TPoolMiningServerThread;
     FPoolThread : TPoolMiningServerThread;
     FMinerOperations : TPCOperationsComp;
     FMinerOperations : TPCOperationsComp;
     FMaxOperationsPerBlock: Integer;
     FMaxOperationsPerBlock: Integer;
@@ -199,12 +200,12 @@ begin
   SetLength(FReceivedBuffer,0);
   SetLength(FReceivedBuffer,0);
   FLockProcessBuffer := TPCCriticalSection.Create('TJSONRPCTcpIpClient_LockProcessBuffer');
   FLockProcessBuffer := TPCCriticalSection.Create('TJSONRPCTcpIpClient_LockProcessBuffer');
   FLockReceivedBuffer := TPCCriticalSection.Create('TJSONRPCTcpIpClient_LockReceivedBuffer');
   FLockReceivedBuffer := TPCCriticalSection.Create('TJSONRPCTcpIpClient_LockReceivedBuffer');
-  FPendingResponseMessages := TPCThreadList.Create('TJSONRPCTcpIpClient_PendingResponseMessages');
+  FPendingResponseMessages := TPCThreadList<Pointer>.Create('TJSONRPCTcpIpClient_PendingResponseMessages');
 end;
 end;
 
 
 destructor TJSONRPCTcpIpClient.Destroy;
 destructor TJSONRPCTcpIpClient.Destroy;
 var P : PPendingResponseMessage;
 var P : PPendingResponseMessage;
-  l : TList;
+  l : TList<Pointer>;
   i : Integer;
   i : Integer;
 begin
 begin
   l := FPendingResponseMessages.LockList;
   l := FPendingResponseMessages.LockList;
@@ -232,7 +233,7 @@ var last_bytes_read : Integer;
   i,lasti : Integer;
   i,lasti : Integer;
   continue : Boolean;
   continue : Boolean;
   procedure FlushBufferPendingMessages(doSearchId : Boolean; idValue : Integer);
   procedure FlushBufferPendingMessages(doSearchId : Boolean; idValue : Integer);
-  var l : TList;
+  var l : TList<Pointer>;
     i : Integer;
     i : Integer;
     P : PPendingResponseMessage;
     P : PPendingResponseMessage;
   Begin
   Begin
@@ -392,7 +393,6 @@ Var json : TPCJSONObject;
   stream : TMemoryStream;
   stream : TMemoryStream;
   b : Byte;
   b : Byte;
   P : PPendingResponseMessage;
   P : PPendingResponseMessage;
-  l : TList;
 begin
 begin
   json := TPCJSONObject.Create;
   json := TPCJSONObject.Create;
   Try
   Try
@@ -515,7 +515,8 @@ Type
 procedure TPoolMiningServer.CaptureNewJobAndSendToMiners;
 procedure TPoolMiningServer.CaptureNewJobAndSendToMiners;
 Var P, PToDelete : PPoolJob;
 Var P, PToDelete : PPoolJob;
   i : Integer;
   i : Integer;
-  l : TList;
+  l : TList<Pointer>;
+  l2 : TList<TNetTcpIpClient>;
   doAdd : Boolean;
   doAdd : Boolean;
   params : TPCJSONObject;
   params : TPCJSONObject;
   OpB : TOperationBlock;
   OpB : TOperationBlock;
@@ -575,13 +576,13 @@ begin
   if (doAdd) And (Assigned(P)) then begin
   if (doAdd) And (Assigned(P)) then begin
     params := TPCJSONObject.Create;
     params := TPCJSONObject.Create;
     Try
     Try
-      l := NetTcpIpClientsLock;
+      l2 := NetTcpIpClientsLock;
       Try
       Try
-        for i := 0 to l.Count - 1 do begin
+        for i := 0 to l2.Count - 1 do begin
           if Not Active then exit;
           if Not Active then exit;
-          SendJobToMiner(P^.OperationsComp,l[i],false,null);
+          SendJobToMiner(P^.OperationsComp,l2[i] as TJSONRPCTcpIpClient,false,null);
         end;
         end;
-        TLog.NewLog(ltDebug,ClassName,'Sending job to miners: '+TPCOperationsComp.OperationBlockToText(P^.OperationsComp.OperationBlock)+' Cache blocks:'+Inttostr(l.Count));
+        TLog.NewLog(ltDebug,ClassName,'Sending job to miners: '+TPCOperationsComp.OperationBlockToText(P^.OperationsComp.OperationBlock)+' Cache blocks:'+Inttostr(l2.Count));
       Finally
       Finally
         NetTcpIpClientsUnlock;
         NetTcpIpClientsUnlock;
       End;
       End;
@@ -594,7 +595,7 @@ end;
 procedure TPoolMiningServer.ClearPoolJobs;
 procedure TPoolMiningServer.ClearPoolJobs;
 Var P : PPoolJob;
 Var P : PPoolJob;
   i : Integer;
   i : Integer;
-  l : TList;
+  l : TList<Pointer>;
 begin
 begin
   l := FPoolJobs.LockList;
   l := FPoolJobs.LockList;
   Try
   Try
@@ -626,7 +627,7 @@ begin
   FMinerOperations := TPCOperationsComp.Create(FNodeNotifyEvents.Node.Bank);
   FMinerOperations := TPCOperationsComp.Create(FNodeNotifyEvents.Node.Bank);
   FMinerAccountKey := CT_TECDSA_Public_Nul;
   FMinerAccountKey := CT_TECDSA_Public_Nul;
   FMinerPayload := Nil;
   FMinerPayload := Nil;
-  FPoolJobs := TPCThreadList.Create('TPoolMiningServer_PoolJobs');
+  FPoolJobs := TPCThreadList<Pointer>.Create('TPoolMiningServer_PoolJobs');
   FPoolThread := TPoolMiningServerThread.Create(Self);
   FPoolThread := TPoolMiningServerThread.Create(Self);
   FMax0FeeOperationsPerBlock := CT_MAX_0_fee_operations_per_block_by_miner;
   FMax0FeeOperationsPerBlock := CT_MAX_0_fee_operations_per_block_by_miner;
   FMaxOperationsPerBlock := CT_MAX_Operations_per_block_by_miner;
   FMaxOperationsPerBlock := CT_MAX_Operations_per_block_by_miner;
@@ -780,7 +781,7 @@ Var s : String;
   p1,p2,p3 : TRawBytes;
   p1,p2,p3 : TRawBytes;
   P : PPoolJob;
   P : PPoolJob;
   i : Integer;
   i : Integer;
-  l : TList;
+  l : TList<Pointer>;
   _payloadHexa : AnsiString;
   _payloadHexa : AnsiString;
   _payloadRaw : TRawBytes;
   _payloadRaw : TRawBytes;
   _timestamp, _nOnce : Cardinal;
   _timestamp, _nOnce : Cardinal;
@@ -912,7 +913,7 @@ var params : TPCJSONObject;
   ts : Cardinal;
   ts : Cardinal;
 Var P : PPoolJob;
 Var P : PPoolJob;
   i,nJobs : Integer;
   i,nJobs : Integer;
-  l : TList;
+  l : TList<Pointer>;
 begin
 begin
   if FClientsCount<=0 then exit;
   if FClientsCount<=0 then exit;
   if (Not Assigned(Operations)) then begin
   if (Not Assigned(Operations)) then begin

+ 6 - 5
src/core/URPC.pas

@@ -29,6 +29,7 @@ Uses UThread, ULog, UConst, UNode, UAccounts, UCrypto, UBlockChain,
   UJSONFunctions, classes, blcksock, synsock,
   UJSONFunctions, classes, blcksock, synsock,
   IniFiles, Variants, math, UBaseTypes, UOpenSSL,
   IniFiles, Variants, math, UBaseTypes, UOpenSSL,
   UPCOrderedLists, UPCDataTypes,
   UPCOrderedLists, UPCDataTypes,
+  {$IFNDEF FPC}System.Generics.Collections{$ELSE}Generics.Collections{$ENDIF},
   UNetProtection;
   UNetProtection;
 
 
 Const
 Const
@@ -787,7 +788,7 @@ function TRPCProcess.ProcessMethod(const method: String; params: TPCJSONObject;
   end;
   end;
 
 
   Function GetAccountOperations(accountNumber : Cardinal; jsonArray : TPCJSONArray; maxBlocksDepth, startReg, maxReg: Integer; forceStartBlock : Cardinal) : Boolean;
   Function GetAccountOperations(accountNumber : Cardinal; jsonArray : TPCJSONArray; maxBlocksDepth, startReg, maxReg: Integer; forceStartBlock : Cardinal) : Boolean;
-  var list : TList;
+  var list : TList<Cardinal>;
     Op : TPCOperation;
     Op : TPCOperation;
     OPR : TOperationResume;
     OPR : TOperationResume;
     Obj : TPCJSONObject;
     Obj : TPCJSONObject;
@@ -806,7 +807,7 @@ function TRPCProcess.ProcessMethod(const method: String; params: TPCJSONObject;
       if ((startReg=-1) And (forceStartBlock=0)) then begin
       if ((startReg=-1) And (forceStartBlock=0)) then begin
         // 1.5.5 change: If start=-1 then will include PENDING OPERATIONS, otherwise not.
         // 1.5.5 change: If start=-1 then will include PENDING OPERATIONS, otherwise not.
         // Only will return pending operations if start=0, otherwise
         // Only will return pending operations if start=0, otherwise
-        list := TList.Create;
+        list := TList<Cardinal>.Create;
         Try
         Try
           FNode.Operations.OperationsHashTree.GetOperationsAffectingAccount(accountNumber,list);
           FNode.Operations.OperationsHashTree.GetOperationsAffectingAccount(accountNumber,list);
           for i := list.Count - 1 downto 0 do begin
           for i := list.Count - 1 downto 0 do begin
@@ -842,7 +843,7 @@ function TRPCProcess.ProcessMethod(const method: String; params: TPCJSONObject;
 
 
   Procedure GetConnections;
   Procedure GetConnections;
   var i : Integer;
   var i : Integer;
-    l : TList;
+    l : TList<TNetConnection>;
     nc : TNetConnection;
     nc : TNetConnection;
     obj: TPCJSONObject;
     obj: TPCJSONObject;
   Begin
   Begin
@@ -2574,7 +2575,7 @@ function TRPCProcess.ProcessMethod(const method: String; params: TPCJSONObject;
     senderOperationsHashTree : TOperationsHashTree;
     senderOperationsHashTree : TOperationsHashTree;
     j,iKey,nSignedAccounts : Integer;
     j,iKey,nSignedAccounts : Integer;
     mop : TOpMultiOperation;
     mop : TOpMultiOperation;
-    lSigners : TList;
+    lSigners : TList<Cardinal>;
     nAccount : Integer;
     nAccount : Integer;
     pubKey : TAccountKey;
     pubKey : TAccountKey;
   begin
   begin
@@ -2592,7 +2593,7 @@ function TRPCProcess.ProcessMethod(const method: String; params: TPCJSONObject;
     end;
     end;
     Try
     Try
       nSignedAccounts := 0;
       nSignedAccounts := 0;
-      lSigners := TList.Create;
+      lSigners := TList<Cardinal>.Create;
       Try
       Try
         mop.SignerAccounts(lSigners);
         mop.SignerAccounts(lSigners);
         for j:=0 to lSigners.Count-1 do begin
         for j:=0 to lSigners.Count-1 do begin

+ 1 - 1
src/core/URandomHash.pas

@@ -103,7 +103,7 @@ unit URandomHash;
 
 
 interface
 interface
 
 
-uses Generics.Collections, SysUtils, HlpIHash, HlpBits, HlpHashFactory;
+uses {$IFNDEF FPC}System.Generics.Collections{$ELSE}Generics.Collections{$ENDIF}, SysUtils, HlpIHash, HlpBits, HlpHashFactory;
 
 
 type
 type
 
 

+ 11 - 9
src/core/UTCPIP.pas

@@ -19,7 +19,7 @@ unit UTCPIP;
 interface
 interface
 
 
 {$IFDEF FPC}
 {$IFDEF FPC}
-  {$mode objfpc}
+  {$mode delphi}
 {$ENDIF}
 {$ENDIF}
 
 
 {$I config.inc}
 {$I config.inc}
@@ -42,7 +42,9 @@ uses
   IdTcpClient, IdTCPServer, IdGlobal, IdContext, IdTCPConnection,
   IdTcpClient, IdTCPServer, IdGlobal, IdContext, IdTCPConnection,
   {$ENDIF}
   {$ENDIF}
   Classes, Sysutils, UBaseTypes,
   Classes, Sysutils, UBaseTypes,
-  UThread, SyncObjs;
+  UThread,
+  {$IFNDEF FPC}System.Generics.Collections{$ELSE}Generics.Collections{$ENDIF},
+  SyncObjs;
 
 
 type
 type
   {$IFDEF DelphiSockets}
   {$IFDEF DelphiSockets}
@@ -172,7 +174,7 @@ type
     FPort : Word;
     FPort : Word;
     FActive : Boolean;
     FActive : Boolean;
     {$ENDIF}
     {$ENDIF}
-    FNetClients : TPCThreadList;
+    FNetClients : TPCThreadList<TNetTcpIpClient>;
     FMaxConnections : Integer;
     FMaxConnections : Integer;
     FNetTcpIpClientClass : TNetTcpIpClientClass;
     FNetTcpIpClientClass : TNetTcpIpClientClass;
     function GetActive: Boolean;
     function GetActive: Boolean;
@@ -191,7 +193,7 @@ type
     Property Port : Word read GetPort Write SetPort;
     Property Port : Word read GetPort Write SetPort;
     Property MaxConnections : Integer read FMaxConnections Write SetMaxConnections;
     Property MaxConnections : Integer read FMaxConnections Write SetMaxConnections;
     Property NetTcpIpClientClass : TNetTcpIpClientClass read FNetTcpIpClientClass write SetNetTcpIpClientClass;
     Property NetTcpIpClientClass : TNetTcpIpClientClass read FNetTcpIpClientClass write SetNetTcpIpClientClass;
-    Function NetTcpIpClientsLock : TList;
+    Function NetTcpIpClientsLock : TList<TNetTcpIpClient>;
     Procedure NetTcpIpClientsUnlock;
     Procedure NetTcpIpClientsUnlock;
     Procedure WaitUntilNetTcpIpClientsFinalized;
     Procedure WaitUntilNetTcpIpClientsFinalized;
   End;
   End;
@@ -753,7 +755,7 @@ begin
   {$ELSE}
   {$ELSE}
   FActive := false;
   FActive := false;
   {$ENDIF}
   {$ENDIF}
-  FNetClients := TPCThreadList.Create('TNetTcpIpServer_NetClients');
+  FNetClients := TPCThreadList<TNetTcpIpClient>.Create('TNetTcpIpServer_NetClients');
 end;
 end;
 
 
 destructor TNetTcpIpServer.Destroy;
 destructor TNetTcpIpServer.Destroy;
@@ -793,7 +795,7 @@ begin
   {$ENDIF}
   {$ENDIF}
 end;
 end;
 
 
-function TNetTcpIpServer.NetTcpIpClientsLock: TList;
+function TNetTcpIpServer.NetTcpIpClientsLock: TList<TNetTcpIpClient>;
 begin
 begin
   Result := FNetClients.LockList;
   Result := FNetClients.LockList;
 end;
 end;
@@ -884,7 +886,7 @@ begin
 end;
 end;
 
 
 procedure TNetTcpIpServer.WaitUntilNetTcpIpClientsFinalized;
 procedure TNetTcpIpServer.WaitUntilNetTcpIpClientsFinalized;
-Var l : TList;
+Var l : TList<TNetTcpIpClient>;
 begin
 begin
   if Active then Active := false;
   if Active then Active := false;
   Repeat
   Repeat
@@ -904,7 +906,7 @@ end;
 procedure TTcpIpServerListenerThread.BCExecute;
 procedure TTcpIpServerListenerThread.BCExecute;
 var ClientSocket: TSocket;
 var ClientSocket: TSocket;
     ClientThread: TTcpIpSocketThread;
     ClientThread: TTcpIpSocketThread;
-    lSockets : TList;
+    lSockets : TList<TTcpIpSocketThread>;
     i : Integer;
     i : Integer;
 begin
 begin
   FServerSocket.CreateSocket;
   FServerSocket.CreateSocket;
@@ -920,7 +922,7 @@ begin
     exit;
     exit;
   end;
   end;
   FServerSocket.Listen;
   FServerSocket.Listen;
-  lSockets := TList.Create;
+  lSockets := TList<TTcpIpSocketThread>.Create;
   try
   try
     while (Not Terminated) And (FNetTcpIpServerServer.Active) do begin
     while (Not Terminated) And (FNetTcpIpServerServer.Active) do begin
       If (FServerSocket.CanRead(100)) And (lSockets.Count<FNetTcpIpServerServer.MaxConnections) then begin
       If (FServerSocket.CanRead(100)) And (lSockets.Count<FNetTcpIpServerServer.MaxConnections) then begin

+ 24 - 23
src/core/UThread.pas

@@ -30,6 +30,7 @@ uses
 {$ELSE}
 {$ELSE}
   {$IFDEF LINUX}cthreads,{$ENDIF}
   {$IFDEF LINUX}cthreads,{$ENDIF}
 {$ENDIF}
 {$ENDIF}
+  {$IFNDEF FPC}System.Generics.Collections{$ELSE}Generics.Collections{$ENDIF},
   Classes, SyncObjs, UBaseTypes;
   Classes, SyncObjs, UBaseTypes;
 
 
 {$I config.inc}
 {$I config.inc}
@@ -80,18 +81,18 @@ Type
     property Terminated;
     property Terminated;
   End;
   End;
 
 
-  TPCThreadList = class
+  TPCThreadList<T> = class
   private
   private
-    FList: TList;
+    FList: TList<T>;
     FLock: TPCCriticalSection;
     FLock: TPCCriticalSection;
   public
   public
     constructor Create(const AName : String);
     constructor Create(const AName : String);
     destructor Destroy; override;
     destructor Destroy; override;
-    function Add(Item: Pointer) : Integer;
+    function Add(Item: T) : Integer;
     procedure Clear;
     procedure Clear;
-    procedure Remove(Item: Pointer); inline;
-    function LockList: TList;
-    function TryLockList(MaxWaitMilliseconds : Cardinal; var lockedList : TList) : Boolean;
+    procedure Remove(Item: T); inline;
+    function LockList: TList<T>;
+    function TryLockList(MaxWaitMilliseconds : Cardinal; var lockedList : TList<T>) : Boolean;
     procedure UnlockList; inline;
     procedure UnlockList; inline;
   end;
   end;
 
 
@@ -103,7 +104,7 @@ uses
 
 
 { TPCThread }
 { TPCThread }
 
 
-Var _threads : TPCThreadList;
+Var _threads : TPCThreadList<TPCThread>;
 
 
 
 
 
 
@@ -124,7 +125,7 @@ begin
 end;
 end;
 
 
 procedure TPCThread.Execute;
 procedure TPCThread.Execute;
-Var l : TList;
+Var l : TList<TPCThread>;
   i : Integer;
   i : Integer;
 begin
 begin
   FStartTickCount := TPlatform.GetTickCount;
   FStartTickCount := TPlatform.GetTickCount;
@@ -159,7 +160,7 @@ begin
 end;
 end;
 
 
 class function TPCThread.GetThread(index: Integer): TPCThread;
 class function TPCThread.GetThread(index: Integer): TPCThread;
-Var l : TList;
+Var l : TList<TPCThread>;
 begin
 begin
   Result := Nil;
   Result := Nil;
   l := _threads.LockList;
   l := _threads.LockList;
@@ -172,7 +173,7 @@ begin
 end;
 end;
 
 
 class function TPCThread.GetThreadByClass(tclass: TPCThreadClass; Exclude: TObject): TPCThread;
 class function TPCThread.GetThreadByClass(tclass: TPCThreadClass; Exclude: TObject): TPCThread;
-Var l : TList;
+Var l : TList<TPCThread>;
   i : Integer;
   i : Integer;
 begin
 begin
   Result := Nil;
   Result := Nil;
@@ -202,7 +203,7 @@ begin
 end;
 end;
 
 
 class function TPCThread.ThreadClassFound(tclass: TPCThreadClass; Exclude : TObject): Integer;
 class function TPCThread.ThreadClassFound(tclass: TPCThreadClass; Exclude : TObject): Integer;
-Var l : TList;
+Var l : TList<TPCThread>;
 begin
 begin
   Result := -1;
   Result := -1;
   if Not Assigned(_threads) then exit;
   if Not Assigned(_threads) then exit;
@@ -218,7 +219,7 @@ begin
 end;
 end;
 
 
 class function TPCThread.ThreadCount: Integer;
 class function TPCThread.ThreadCount: Integer;
-Var l : TList;
+Var l : TList<TPCThread>;
 begin
 begin
   l := _threads.LockList;
   l := _threads.LockList;
   try
   try
@@ -229,7 +230,7 @@ begin
 end;
 end;
 
 
 class procedure TPCThread.ThreadsListInfo(list: TStrings);
 class procedure TPCThread.ThreadsListInfo(list: TStrings);
-Var l : TList;
+Var l : TList<TPCThread>;
   i : Integer;
   i : Integer;
 begin
 begin
   l := _threads.LockList;
   l := _threads.LockList;
@@ -286,7 +287,7 @@ end;
 
 
 { TPCThreadList }
 { TPCThreadList }
 
 
-function TPCThreadList.Add(Item: Pointer) : Integer;
+function TPCThreadList<T>.Add(Item: T) : Integer;
 begin
 begin
   LockList;
   LockList;
   Try
   Try
@@ -296,7 +297,7 @@ begin
   End;
   End;
 end;
 end;
 
 
-procedure TPCThreadList.Clear;
+procedure TPCThreadList<T>.Clear;
 begin
 begin
   LockList;
   LockList;
   Try
   Try
@@ -306,13 +307,13 @@ begin
   End;
   End;
 end;
 end;
 
 
-constructor TPCThreadList.Create(const AName : String);
+constructor TPCThreadList<T>.Create(const AName : String);
 begin
 begin
   FLock := TPCCriticalSection.Create(AName);
   FLock := TPCCriticalSection.Create(AName);
-  FList := TList.Create;
+  FList := TList<T>.Create;
 end;
 end;
 
 
-destructor TPCThreadList.Destroy;
+destructor TPCThreadList<T>.Destroy;
 begin
 begin
   LockList;
   LockList;
   try
   try
@@ -324,13 +325,13 @@ begin
   end;
   end;
 end;
 end;
 
 
-function TPCThreadList.LockList: TList;
+function TPCThreadList<T>.LockList: TList<T>;
 begin
 begin
   TPCThread.ProtectEnterCriticalSection(Self,FLock);
   TPCThread.ProtectEnterCriticalSection(Self,FLock);
   Result := FList;
   Result := FList;
 end;
 end;
 
 
-procedure TPCThreadList.Remove(Item: Pointer);
+procedure TPCThreadList<T>.Remove(Item: T);
 begin
 begin
   LockList;
   LockList;
   try
   try
@@ -340,13 +341,13 @@ begin
   end;
   end;
 end;
 end;
 
 
-function TPCThreadList.TryLockList(MaxWaitMilliseconds: Cardinal; var lockedList: TList): Boolean;
+function TPCThreadList<T>.TryLockList(MaxWaitMilliseconds: Cardinal; var lockedList: TList<T>): Boolean;
 begin
 begin
   lockedList := FList;
   lockedList := FList;
   Result := TPCThread.TryProtectEnterCriticalSection(Self,MaxWaitMilliseconds,FLock);
   Result := TPCThread.TryProtectEnterCriticalSection(Self,MaxWaitMilliseconds,FLock);
 end;
 end;
 
 
-procedure TPCThreadList.UnlockList;
+procedure TPCThreadList<T>.UnlockList;
 begin
 begin
   FLock.Release;
   FLock.Release;
 end;
 end;
@@ -441,7 +442,7 @@ end;
 {$ENDIF}
 {$ENDIF}
 
 
 initialization
 initialization
-  _threads := TPCThreadList.Create('GLOBAL_THREADS');
+  _threads := TPCThreadList<TPCThread>.Create('GLOBAL_THREADS');
 finalization
 finalization
   FreeAndNil(_threads);
   FreeAndNil(_threads);
 end.
 end.

+ 10 - 8
src/core/UTxMultiOperation.pas

@@ -23,7 +23,9 @@ unit UTxMultiOperation;
 interface
 interface
 
 
 uses
 uses
-  Classes, SysUtils, UCrypto, UBlockChain, UAccounts, UBaseTypes, UPCDataTypes;
+  Classes, SysUtils, UCrypto, UBlockChain, UAccounts, UBaseTypes,
+  {$IFNDEF FPC}System.Generics.Collections{$ELSE}Generics.Collections{$ENDIF},
+  UPCDataTypes;
 
 
 Type
 Type
 
 
@@ -120,7 +122,7 @@ Type
     function CheckSignatures(AccountTransaction : TPCSafeBoxTransaction; var errors : String) : Boolean;
     function CheckSignatures(AccountTransaction : TPCSafeBoxTransaction; var errors : String) : Boolean;
 
 
     function DoOperation(AccountPreviousUpdatedBlock : TAccountPreviousBlockInfo; AccountTransaction : TPCSafeBoxTransaction; var errors : String) : Boolean; override;
     function DoOperation(AccountPreviousUpdatedBlock : TAccountPreviousBlockInfo; AccountTransaction : TPCSafeBoxTransaction; var errors : String) : Boolean; override;
-    procedure AffectedAccounts(list : TList); override;
+    procedure AffectedAccounts(list : TList<Cardinal>); override;
     //
     //
     Function DoSignMultiOperationSigner(current_protocol : Word; SignerAccount : Cardinal; key : TECPrivateKey) : Integer;
     Function DoSignMultiOperationSigner(current_protocol : Word; SignerAccount : Cardinal; key : TECPrivateKey) : Integer;
     class function OpType : Byte; override;
     class function OpType : Byte; override;
@@ -128,7 +130,7 @@ Type
     function OperationFee : Int64; override;
     function OperationFee : Int64; override;
     function OperationPayload : TRawBytes; override;
     function OperationPayload : TRawBytes; override;
     function SignerAccount : Cardinal; override;
     function SignerAccount : Cardinal; override;
-    procedure SignerAccounts(list : TList); override;
+    procedure SignerAccounts(list : TList<Cardinal>); override;
     function IsSignerAccount(account : Cardinal) : Boolean; override;
     function IsSignerAccount(account : Cardinal) : Boolean; override;
     function DestinationAccount : Int64; override;
     function DestinationAccount : Int64; override;
     function SellerAccount : Int64; override;
     function SellerAccount : Int64; override;
@@ -720,11 +722,11 @@ begin
   Result := True;
   Result := True;
 end;
 end;
 
 
-procedure TOpMultiOperation.AffectedAccounts(list: TList);
+procedure TOpMultiOperation.AffectedAccounts(list: TList<Cardinal>);
 Var i : Integer;
 Var i : Integer;
   Procedure _doAdd(nAcc : Cardinal);
   Procedure _doAdd(nAcc : Cardinal);
   Begin
   Begin
-    If list.IndexOf(TObject(nAcc))<0 then list.Add(TObject(nAcc));
+    If list.IndexOf(nAcc)<0 then list.Add(nAcc);
   end;
   end;
 begin
 begin
   For i:=low(FData.txSenders) to High(FData.txSenders) do begin
   For i:=low(FData.txSenders) to High(FData.txSenders) do begin
@@ -801,15 +803,15 @@ begin
   else Result := MaxInt;
   else Result := MaxInt;
 end;
 end;
 
 
-procedure TOpMultiOperation.SignerAccounts(list: TList);
+procedure TOpMultiOperation.SignerAccounts(list: TList<Cardinal>);
 var i : Integer;
 var i : Integer;
 begin
 begin
   list.Clear;
   list.Clear;
   for i := 0 to High(FData.txSenders) do begin
   for i := 0 to High(FData.txSenders) do begin
-    list.Add(TObject(FData.txSenders[i].Account));
+    list.Add(FData.txSenders[i].Account);
   end;
   end;
   for i:= 0 to High(FData.changesInfo) do begin
   for i:= 0 to High(FData.changesInfo) do begin
-    if list.IndexOf(TObject(FData.changesInfo[i].Account))<0 then list.Add(TObject(FData.changesInfo[i].Account));
+    if list.IndexOf(FData.changesInfo[i].Account)<0 then list.Add(FData.changesInfo[i].Account);
   end;
   end;
 end;
 end;
 
 

+ 15 - 8
src/core/UWallet.pas

@@ -37,6 +37,7 @@ uses
   {$IFDEF INTERNAL_USE_SETTINGS_UNIT}
   {$IFDEF INTERNAL_USE_SETTINGS_UNIT}
   USettings,
   USettings,
   {$ENDIF}
   {$ENDIF}
+  {$IFNDEF FPC}System.Generics.Collections{$ELSE}Generics.Collections{$ENDIF},
   UPCDataTypes;
   UPCDataTypes;
 
 
 Type
 Type
@@ -51,7 +52,7 @@ Type
 
 
   TWalletKeys = Class(TComponent)
   TWalletKeys = Class(TComponent)
   private
   private
-    FSearchableKeys : TList;
+    FSearchableKeys : TList<Pointer>;
     FFileName: String;
     FFileName: String;
     FWalletPassword: String;
     FWalletPassword: String;
     FWalletFileStream : TFileStream;
     FWalletFileStream : TFileStream;
@@ -252,7 +253,7 @@ begin
   FIsValidPassword := false;
   FIsValidPassword := false;
   FWalletFileStream := Nil;
   FWalletFileStream := Nil;
   FWalletPassword := '';
   FWalletPassword := '';
-  FSearchableKeys := TList.Create;
+  FSearchableKeys := TList<Pointer>.Create;
   FIsReadingStream := false;
   FIsReadingStream := false;
 end;
 end;
 
 
@@ -305,6 +306,7 @@ Var i : Integer;
  P : PWalletKey;
  P : PWalletKey;
  raw : TRawBytes;
  raw : TRawBytes;
  isOk : Boolean;
  isOk : Boolean;
+ LtmpECPrivKey : TECPrivateKey;
 begin
 begin
   FIsValidPassword := false;
   FIsValidPassword := false;
   isOk := true;
   isOk := true;
@@ -318,15 +320,20 @@ begin
     if P^.HasPrivateKey then begin
     if P^.HasPrivateKey then begin
       isOk := TPCEncryption.DoPascalCoinAESDecrypt(P^.CryptedKey, TEncoding.ASCII.GetBytes(FWalletPassword), raw );
       isOk := TPCEncryption.DoPascalCoinAESDecrypt(P^.CryptedKey, TEncoding.ASCII.GetBytes(FWalletPassword), raw );
       If isOk then begin
       If isOk then begin
-        P^.PrivateKey := TECPrivateKey.Create;
+        LtmpECPrivKey := TECPrivateKey.Create;
         try
         try
-          P^.PrivateKey.SetPrivateKeyFromHexa(P^.AccountKey.EC_OpenSSL_NID,TEncoding.ASCII.GetString(raw));
-        except on E: Exception do begin
-            P^.PrivateKey.Free;
-            P^.PrivateKey := Nil;
+          LtmpECPrivKey.SetPrivateKeyFromHexa(P^.AccountKey.EC_OpenSSL_NID,TEncoding.ASCII.GetString(raw));
+          if not TAccountComp.EqualAccountKeys(LtmpECPrivKey.PublicKey,P^.AccountKey) then begin
+            TLog.NewLog(lterror,ClassName,Format('Private key and public key does not match! %s <> %s',
+              [TAccountComp.AccountPublicKeyExport(LtmpECPrivKey.PublicKey),
+               TAccountComp.AccountPublicKeyExport(P^.AccountKey)]));
+            LtmpECPrivKey.Free;
+          end else P^.PrivateKey := LtmpECPrivKey;
+        except
+          on E: Exception do begin
+            LtmpECPrivKey.Free;
             isOk := false;
             isOk := false;
             TLog.NewLog(lterror,ClassName,Format('Fatal error when generating EC private key %d/%d: %s',[i+1,FSearchableKeys.Count,E.Message]));
             TLog.NewLog(lterror,ClassName,Format('Fatal error when generating EC private key %d/%d: %s',[i+1,FSearchableKeys.Count,E.Message]));
-            //disabled exit... continue: exit;
           end;
           end;
         end;
         end;
       end;
       end;

+ 4 - 3
src/libraries/pascalcoin/UJSONFunctions.pas

@@ -35,7 +35,8 @@ Uses
   {$ENDIF}
   {$ENDIF}
   DBXJSON,
   DBXJSON,
   {$ENDIF}
   {$ENDIF}
-  SysUtils, DateUtils, Variants, Classes, ULog;
+  SysUtils, DateUtils, Variants, Classes, ULog,
+  {$IFNDEF FPC}System.Generics.Collections{$ELSE}Generics.Collections{$ENDIF};
 
 
 Type
 Type
   {$IFDEF FPC}
   {$IFDEF FPC}
@@ -105,7 +106,7 @@ Type
 
 
   TPCJSONList = Class(TPCJSONData)
   TPCJSONList = Class(TPCJSONData)
   private
   private
-    FList : TList;
+    FList : TList<TPCJSONData>;
     function GetItems(Index: Integer): TPCJSONData;
     function GetItems(Index: Integer): TPCJSONData;
     procedure SetItems(Index: Integer; const Value: TPCJSONData);
     procedure SetItems(Index: Integer; const Value: TPCJSONData);
   protected
   protected
@@ -319,7 +320,7 @@ constructor TPCJSONList.Create;
 begin
 begin
   inherited;
   inherited;
   FParent := Nil;
   FParent := Nil;
-  FList := TList.Create;
+  FList := TList<TPCJSONData>.Create;
 end;
 end;
 
 
 procedure TPCJSONList.Delete(index: Integer);
 procedure TPCJSONList.Delete(index: Integer);