Browse Source

Build 1.0.3

Source code of PascalCoin build 1.0.3
PascalCoin 9 years ago
parent
commit
d600a159c6

BIN
Instaler/PascalCoinWalletB1.0.2.0.exe


BIN
Instaler/PascalCoinWalletB1.0.3.0.exe


BIN
PascalCoinWallet.res


+ 10 - 0
README.md

@@ -38,6 +38,16 @@ If you like it, consider a donation using BitCoin:
 
 
 History:
 History:
 
 
+Build 1.0.3.0 - 2016-09-08
+--------------------------
+- Important changes to database 
+- Peer cache
+- Issues with Connections
+- More stable
+- Miner key selector
+- Invalid local time detector
+
+
 Build 1.0.2.0 - 2016-08-31
 Build 1.0.2.0 - 2016-08-31
 --------------------------
 --------------------------
 - Improved hashing speed
 - Improved hashing speed

+ 10 - 0
README.txt

@@ -38,6 +38,16 @@ If you like it, consider a donation using BitCoin:
 
 
 History:
 History:
 
 
+Build 1.0.3.0 - 2016-09-08
+--------------------------
+- Important changes to database 
+- Peer cache
+- Issues with Connections
+- More stable
+- Miner key selector
+- Invalid local time detector
+
+
 Build 1.0.2.0 - 2016-08-31
 Build 1.0.2.0 - 2016-08-31
 --------------------------
 --------------------------
 - Improved hashing speed
 - Improved hashing speed

+ 0 - 8
Units/Forms/UFRMOperation.dfm

@@ -110,10 +110,6 @@ object FRMOperation: TFRMOperation
     TabOrder = 1
     TabOrder = 1
     object tsOperation: TTabSheet
     object tsOperation: TTabSheet
       TabVisible = False
       TabVisible = False
-      ExplicitLeft = 0
-      ExplicitTop = 0
-      ExplicitWidth = 0
-      ExplicitHeight = 0
       object gbOperation: TGroupBox
       object gbOperation: TGroupBox
         Left = 13
         Left = 13
         Top = 8
         Top = 8
@@ -448,10 +444,6 @@ object FRMOperation: TFRMOperation
     object tsGlobalError: TTabSheet
     object tsGlobalError: TTabSheet
       ImageIndex = 1
       ImageIndex = 1
       TabVisible = False
       TabVisible = False
-      ExplicitLeft = 0
-      ExplicitTop = 0
-      ExplicitWidth = 0
-      ExplicitHeight = 0
       object lblGlobalErrors: TLabel
       object lblGlobalErrors: TLabel
         Left = 40
         Left = 40
         Top = 50
         Top = 50

+ 15 - 6
Units/Forms/UFRMPascalCoinWalletConfig.dfm

@@ -96,14 +96,15 @@ object FRMPascalCoinWalletConfig: TFRMPascalCoinWalletConfig
     Height = 17
     Height = 17
     Caption = 'Save log file'
     Caption = 'Save log file'
     TabOrder = 8
     TabOrder = 8
+    OnClick = cbSaveLogFilesClick
   end
   end
   object cbShowLogs: TCheckBox
   object cbShowLogs: TCheckBox
     Left = 15
     Left = 15
-    Top = 382
+    Top = 397
     Width = 97
     Width = 97
     Height = 17
     Height = 17
     Caption = 'Show logs'
     Caption = 'Show logs'
-    TabOrder = 9
+    TabOrder = 10
   end
   end
   object bbOk: TBitBtn
   object bbOk: TBitBtn
     Left = 171
     Left = 171
@@ -113,7 +114,7 @@ object FRMPascalCoinWalletConfig: TFRMPascalCoinWalletConfig
     DoubleBuffered = True
     DoubleBuffered = True
     Kind = bkOK
     Kind = bkOK
     ParentDoubleBuffered = False
     ParentDoubleBuffered = False
-    TabOrder = 10
+    TabOrder = 11
     OnClick = bbOkClick
     OnClick = bbOkClick
   end
   end
   object bbCancel: TBitBtn
   object bbCancel: TBitBtn
@@ -124,7 +125,7 @@ object FRMPascalCoinWalletConfig: TFRMPascalCoinWalletConfig
     DoubleBuffered = True
     DoubleBuffered = True
     Kind = bkCancel
     Kind = bkCancel
     ParentDoubleBuffered = False
     ParentDoubleBuffered = False
-    TabOrder = 11
+    TabOrder = 12
   end
   end
   object udInternetServerPort: TUpDown
   object udInternetServerPort: TUpDown
     Left = 226
     Left = 226
@@ -231,7 +232,7 @@ object FRMPascalCoinWalletConfig: TFRMPascalCoinWalletConfig
     Width = 171
     Width = 171
     Height = 17
     Height = 17
     Caption = 'Show Modal Messages'
     Caption = 'Show Modal Messages'
-    TabOrder = 12
+    TabOrder = 13
   end
   end
   object udCPUs: TUpDown
   object udCPUs: TUpDown
     Left = 226
     Left = 226
@@ -260,7 +261,7 @@ object FRMPascalCoinWalletConfig: TFRMPascalCoinWalletConfig
     Width = 334
     Width = 334
     Height = 121
     Height = 121
     Caption = ' Miner Private Key: '
     Caption = ' Miner Private Key: '
-    TabOrder = 13
+    TabOrder = 14
     object rbGenerateANewPrivateKeyEachBlock: TRadioButton
     object rbGenerateANewPrivateKeyEachBlock: TRadioButton
       Left = 20
       Left = 20
       Top = 20
       Top = 20
@@ -294,4 +295,12 @@ object FRMPascalCoinWalletConfig: TFRMPascalCoinWalletConfig
       TabOrder = 3
       TabOrder = 3
     end
     end
   end
   end
+  object cbSaveDebugLogs: TCheckBox
+    Left = 31
+    Top = 377
+    Width = 97
+    Height = 17
+    Caption = 'Save debug logs too'
+    TabOrder = 9
+  end
 end
 end

+ 10 - 0
Units/Forms/UFRMPascalCoinWalletConfig.pas

@@ -46,9 +46,11 @@ type
     rbUseARandomKey: TRadioButton;
     rbUseARandomKey: TRadioButton;
     rbMineAllwaysWithThisKey: TRadioButton;
     rbMineAllwaysWithThisKey: TRadioButton;
     cbPrivateKeyToMine: TComboBox;
     cbPrivateKeyToMine: TComboBox;
+    cbSaveDebugLogs: TCheckBox;
     procedure FormCreate(Sender: TObject);
     procedure FormCreate(Sender: TObject);
     procedure bbOkClick(Sender: TObject);
     procedure bbOkClick(Sender: TObject);
     procedure bbUpdatePasswordClick(Sender: TObject);
     procedure bbUpdatePasswordClick(Sender: TObject);
+    procedure cbSaveLogFilesClick(Sender: TObject);
   private
   private
     FAppParams: TAppParams;
     FAppParams: TAppParams;
     FWalletKeys: TWalletKeys;
     FWalletKeys: TWalletKeys;
@@ -93,6 +95,7 @@ begin
   AppParams.ParamByName[CT_PARAM_AutomaticMineWhenConnectedToNodes].SetAsBoolean(cbAutomaticMiningWhenConnectedToNodes.Checked );
   AppParams.ParamByName[CT_PARAM_AutomaticMineWhenConnectedToNodes].SetAsBoolean(cbAutomaticMiningWhenConnectedToNodes.Checked );
   AppParams.ParamByName[CT_PARAM_SaveLogFiles].SetAsBoolean(cbSaveLogFiles.Checked );
   AppParams.ParamByName[CT_PARAM_SaveLogFiles].SetAsBoolean(cbSaveLogFiles.Checked );
   AppParams.ParamByName[CT_PARAM_ShowLogs].SetAsBoolean(cbShowLogs.Checked );
   AppParams.ParamByName[CT_PARAM_ShowLogs].SetAsBoolean(cbShowLogs.Checked );
+  AppParams.ParamByName[CT_PARAM_SaveDebugLogs].SetAsBoolean(cbSaveDebugLogs.Checked);
   AppParams.ParamByName[CT_PARAM_MinerName].SetAsString(ebMinerName.Text);
   AppParams.ParamByName[CT_PARAM_MinerName].SetAsString(ebMinerName.Text);
   AppParams.ParamByName[CT_PARAM_ShowModalMessages].SetAsBoolean(cbShowModalMessages.Checked);
   AppParams.ParamByName[CT_PARAM_ShowModalMessages].SetAsBoolean(cbShowModalMessages.Checked);
   AppParams.ParamByName[CT_PARAM_MaxCPUs].SetAsInteger(udCPUs.Position);
   AppParams.ParamByName[CT_PARAM_MaxCPUs].SetAsInteger(udCPUs.Position);
@@ -126,6 +129,11 @@ begin
   UpdateWalletConfig;
   UpdateWalletConfig;
 end;
 end;
 
 
+procedure TFRMPascalCoinWalletConfig.cbSaveLogFilesClick(Sender: TObject);
+begin
+  cbSaveDebugLogs.Enabled := cbSaveLogFiles.Checked;
+end;
+
 procedure TFRMPascalCoinWalletConfig.FormCreate(Sender: TObject);
 procedure TFRMPascalCoinWalletConfig.FormCreate(Sender: TObject);
 begin
 begin
   lblDefaultInternetServerPort.Caption := Format('(Default %d)',[CT_NetServer_Port]);
   lblDefaultInternetServerPort.Caption := Format('(Default %d)',[CT_NetServer_Port]);
@@ -156,6 +164,7 @@ begin
     UpdateWalletConfig;
     UpdateWalletConfig;
     cbSaveLogFiles.Checked := AppParams.ParamByName[CT_PARAM_SaveLogFiles].GetAsBoolean(false);
     cbSaveLogFiles.Checked := AppParams.ParamByName[CT_PARAM_SaveLogFiles].GetAsBoolean(false);
     cbShowLogs.Checked := AppParams.ParamByName[CT_PARAM_ShowLogs].GetAsBoolean(false);
     cbShowLogs.Checked := AppParams.ParamByName[CT_PARAM_ShowLogs].GetAsBoolean(false);
+    cbSaveDebugLogs.Checked := AppParams.ParamByName[CT_PARAM_SaveDebugLogs].GetAsBoolean(false);
     ebMinerName.Text := AppParams.ParamByName[CT_PARAM_MinerName].GetAsString('');
     ebMinerName.Text := AppParams.ParamByName[CT_PARAM_MinerName].GetAsString('');
     cbShowModalMessages.Checked := AppParams.ParamByName[CT_PARAM_ShowModalMessages].GetAsBoolean(false);
     cbShowModalMessages.Checked := AppParams.ParamByName[CT_PARAM_ShowModalMessages].GetAsBoolean(false);
     udCPUs.Position := AppParams.ParamByName[CT_PARAM_MaxCPUs].GetAsInteger(1);
     udCPUs.Position := AppParams.ParamByName[CT_PARAM_MaxCPUs].GetAsInteger(1);
@@ -164,6 +173,7 @@ begin
       TLog.NewLog(lterror,ClassName,'Exception at SetAppParams: '+E.Message);
       TLog.NewLog(lterror,ClassName,'Exception at SetAppParams: '+E.Message);
     end;
     end;
   End;
   End;
+  cbSaveLogFilesClick(nil);
 end;
 end;
 
 
 procedure TFRMPascalCoinWalletConfig.SetWalletKeys(const Value: TWalletKeys);
 procedure TFRMPascalCoinWalletConfig.SetWalletKeys(const Value: TWalletKeys);

+ 44 - 18
Units/Forms/UFRMWallet.dfm

@@ -327,12 +327,12 @@ object FRMWallet: TFRMWallet
       ParentFont = False
       ParentFont = False
       OnClick = lblReceivedMessagesClick
       OnClick = lblReceivedMessagesClick
     end
     end
-    object Label15: TLabel
-      Left = 721
+    object lblBuild: TLabel
+      Left = 717
       Top = 6
       Top = 6
-      Width = 112
+      Width = 49
       Height = 23
       Height = 23
-      Caption = 'TEST MODE'
+      Caption = 'Build'
       Font.Charset = DEFAULT_CHARSET
       Font.Charset = DEFAULT_CHARSET
       Font.Color = clWindowText
       Font.Color = clWindowText
       Font.Height = -19
       Font.Height = -19
@@ -343,7 +343,7 @@ object FRMWallet: TFRMWallet
     object cbAllowMining: TCheckBox
     object cbAllowMining: TCheckBox
       Left = 620
       Left = 620
       Top = 10
       Top = 10
-      Width = 97
+      Width = 91
       Height = 17
       Height = 17
       Caption = 'Allow Mining'
       Caption = 'Allow Mining'
       TabOrder = 0
       TabOrder = 0
@@ -375,16 +375,20 @@ object FRMWallet: TFRMWallet
     Top = 91
     Top = 91
     Width = 899
     Width = 899
     Height = 448
     Height = 448
-    ActivePage = tsAccountsExplorer
+    ActivePage = tsNodeStats
     Align = alClient
     Align = alClient
     TabOrder = 2
     TabOrder = 2
     OnChange = PageControlChange
     OnChange = PageControlChange
     object tsAccountsExplorer: TTabSheet
     object tsAccountsExplorer: TTabSheet
       Caption = 'Accounts Explorer'
       Caption = 'Accounts Explorer'
+      ExplicitLeft = 0
+      ExplicitTop = 0
+      ExplicitWidth = 0
+      ExplicitHeight = 0
       object Splitter1: TSplitter
       object Splitter1: TSplitter
         Left = 380
         Left = 380
-        Top = 41
-        Height = 379
+        Top = 66
+        Height = 354
         ExplicitLeft = 390
         ExplicitLeft = 390
         ExplicitTop = 140
         ExplicitTop = 140
         ExplicitHeight = 100
         ExplicitHeight = 100
@@ -393,9 +397,16 @@ object FRMWallet: TFRMWallet
         Left = 0
         Left = 0
         Top = 0
         Top = 0
         Width = 891
         Width = 891
-        Height = 41
+        Height = 66
         Align = alTop
         Align = alTop
         TabOrder = 0
         TabOrder = 0
+        object Label18: TLabel
+          Left = 11
+          Top = 35
+          Width = 61
+          Height = 13
+          Caption = 'Find account'
+        end
         object cbMyPrivateKeys: TComboBox
         object cbMyPrivateKeys: TComboBox
           Left = 260
           Left = 260
           Top = 7
           Top = 7
@@ -414,21 +425,36 @@ object FRMWallet: TFRMWallet
           TabOrder = 1
           TabOrder = 1
           OnClick = cbExploreMyAccountsClick
           OnClick = cbExploreMyAccountsClick
         end
         end
+        object ebFindAccountNumber: TEdit
+          Left = 87
+          Top = 32
+          Width = 83
+          Height = 21
+          TabOrder = 2
+          OnChange = ebFindAccountNumberChange
+          OnExit = ebFindAccountNumberExit
+        end
       end
       end
       object dgAccountOperations: TDrawGrid
       object dgAccountOperations: TDrawGrid
         Left = 383
         Left = 383
-        Top = 41
+        Top = 66
         Width = 508
         Width = 508
-        Height = 379
+        Height = 354
         Align = alClient
         Align = alClient
         TabOrder = 1
         TabOrder = 1
         OnDblClick = MiDecodePayloadClick
         OnDblClick = MiDecodePayloadClick
+        RowHeights = (
+          24
+          24
+          24
+          24
+          24)
       end
       end
       object pnlAccounts: TPanel
       object pnlAccounts: TPanel
         Left = 0
         Left = 0
-        Top = 41
+        Top = 66
         Width = 380
         Width = 380
-        Height = 379
+        Height = 354
         Align = alLeft
         Align = alLeft
         BevelOuter = bvNone
         BevelOuter = bvNone
         TabOrder = 2
         TabOrder = 2
@@ -436,7 +462,7 @@ object FRMWallet: TFRMWallet
           Left = 0
           Left = 0
           Top = 0
           Top = 0
           Width = 380
           Width = 380
-          Height = 345
+          Height = 320
           Align = alLeft
           Align = alLeft
           TabOrder = 0
           TabOrder = 0
           OnClick = dgAccountsClick
           OnClick = dgAccountsClick
@@ -451,7 +477,7 @@ object FRMWallet: TFRMWallet
         end
         end
         object pnlAccountsInfo: TPanel
         object pnlAccountsInfo: TPanel
           Left = 0
           Left = 0
-          Top = 345
+          Top = 320
           Width = 380
           Width = 380
           Height = 34
           Height = 34
           Align = alBottom
           Align = alBottom
@@ -1014,10 +1040,10 @@ object FRMWallet: TFRMWallet
   end
   end
   object ImageListIcons: TImageList
   object ImageListIcons: TImageList
     Height = 48
     Height = 48
-    Left = 90
-    Top = 155
+    Left = 105
+    Top = 180
     Bitmap = {
     Bitmap = {
-      494C0101020008009C0010003000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600
+      494C010102000800C00010003000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600
       0000000000003600000028000000400000003000000001002000000000000030
       0000000000003600000028000000400000003000000001002000000000000030
       0000000000000000000000000000000000000000000000000000000000000000
       0000000000000000000000000000000000000000000000000000000000000000
       0000000000000000002A292929D60B0B0BF4111111EE0000006B000000000000
       0000000000000000002A292929D60B0B0BF4111111EE0000006B000000000000

+ 103 - 63
Units/Forms/UFRMWallet.pas

@@ -32,11 +32,13 @@ Const
   CT_PARAM_MinerPrivateKeyType = 'MinerPrivateKeyType';
   CT_PARAM_MinerPrivateKeyType = 'MinerPrivateKeyType';
   CT_PARAM_MinerPrivateKeySelectedPublicKey = 'MinerPrivateKeySelectedPublicKey';
   CT_PARAM_MinerPrivateKeySelectedPublicKey = 'MinerPrivateKeySelectedPublicKey';
   CT_PARAM_SaveLogFiles = 'SaveLogFiles';
   CT_PARAM_SaveLogFiles = 'SaveLogFiles';
+  CT_PARAM_SaveDebugLogs = 'SaveDebugLogs';
   CT_PARAM_ShowLogs = 'ShowLogs';
   CT_PARAM_ShowLogs = 'ShowLogs';
   CT_PARAM_MinerName = 'MinerName';
   CT_PARAM_MinerName = 'MinerName';
   CT_PARAM_FirstTime = 'FirstTime';
   CT_PARAM_FirstTime = 'FirstTime';
   CT_PARAM_ShowModalMessages = 'ShowModalMessages';
   CT_PARAM_ShowModalMessages = 'ShowModalMessages';
   CT_PARAM_MaxCPUs = 'MaxCPUs';
   CT_PARAM_MaxCPUs = 'MaxCPUs';
+  CT_PARAM_PeerCache = 'PeerCache';
 
 
 type
 type
   TStringListAux = Class(TStringList)
   TStringListAux = Class(TStringList)
@@ -143,7 +145,9 @@ type
     lblAccountsCount: TLabel;
     lblAccountsCount: TLabel;
     lblAccountsBalance: TLabel;
     lblAccountsBalance: TLabel;
     lblReceivedMessages: TLabel;
     lblReceivedMessages: TLabel;
-    Label15: TLabel;
+    lblBuild: TLabel;
+    ebFindAccountNumber: TEdit;
+    Label18: TLabel;
     procedure FormCreate(Sender: TObject);
     procedure FormCreate(Sender: TObject);
     procedure FormDestroy(Sender: TObject);
     procedure FormDestroy(Sender: TObject);
     procedure TimerUpdateStatusTimer(Sender: TObject);
     procedure TimerUpdateStatusTimer(Sender: TObject);
@@ -171,6 +175,8 @@ type
     procedure ApplicationEventsMinimize(Sender: TObject);
     procedure ApplicationEventsMinimize(Sender: TObject);
     procedure bbSendAMessageClick(Sender: TObject);
     procedure bbSendAMessageClick(Sender: TObject);
     procedure lblReceivedMessagesClick(Sender: TObject);
     procedure lblReceivedMessagesClick(Sender: TObject);
+    procedure ebFindAccountNumberChange(Sender: TObject);
+    procedure ebFindAccountNumberExit(Sender: TObject);
   private
   private
     FMinersBlocksFound: Integer;
     FMinersBlocksFound: Integer;
     procedure SetMinersBlocksFound(const Value: Integer);
     procedure SetMinersBlocksFound(const Value: Integer);
@@ -191,14 +197,11 @@ type
     FOperationsDBGrid : TOperationsDBGrid;
     FOperationsDBGrid : TOperationsDBGrid;
     FBlockChainDBGrid : TBlockChainDBGrid;
     FBlockChainDBGrid : TBlockChainDBGrid;
     FMinerPrivateKeyType : TMinerPrivateKey;
     FMinerPrivateKeyType : TMinerPrivateKey;
-    FMemoNetConnections : TStringListAux;
-    FMemoBlackListNodes : TStringListAux;
-    FMemoAvailableNodeServers : TStringListAux;
     FUpdating : Boolean;
     FUpdating : Boolean;
     FMessagesUnreadCount : Integer;
     FMessagesUnreadCount : Integer;
     Procedure CheckMining;
     Procedure CheckMining;
     Procedure OnNewAccount(Sender : TObject);
     Procedure OnNewAccount(Sender : TObject);
-    Procedure OnReceivedHelloResponse(Sender : TObject);
+    Procedure OnReceivedHelloMessage(Sender : TObject);
     Procedure OnNetStatisticsChanged(Sender : TObject);
     Procedure OnNetStatisticsChanged(Sender : TObject);
     procedure OnNewLog(logtype : TLogType; Time : TDateTime; ThreadID : Cardinal; Const sender, logtext : AnsiString);
     procedure OnNewLog(logtype : TLogType; Time : TDateTime; ThreadID : Cardinal; Const sender, logtext : AnsiString);
     procedure OnMinerNewBlockFound(sender : TMinerThread; Operations : TPCOperationsComp);
     procedure OnMinerNewBlockFound(sender : TMinerThread; Operations : TPCOperationsComp);
@@ -249,7 +252,6 @@ procedure TThreadActivate.BCExecute;
 begin
 begin
   // Read Operations saved from disk
   // Read Operations saved from disk
   TNode.Node.Bank.DiskRestoreFromOperations(CT_MaxBlock);
   TNode.Node.Bank.DiskRestoreFromOperations(CT_MaxBlock);
-  // Activating server
   TNode.Node.AutoDiscoverNodes(CT_Discover_IPs);
   TNode.Node.AutoDiscoverNodes(CT_Discover_IPs);
   TNode.Node.NetServer.Active := true;
   TNode.Node.NetServer.Active := true;
   FRMWallet.UpdateAccounts;
   FRMWallet.UpdateAccounts;
@@ -278,9 +280,10 @@ begin
     // Creating Node:
     // Creating Node:
     FNode := TNode.Node;
     FNode := TNode.Node;
     FNode.NetServer.Port := FAppParams.ParamByName[CT_PARAM_InternetServerPort].GetAsInteger(CT_NetServer_Port);
     FNode.NetServer.Port := FAppParams.ParamByName[CT_PARAM_InternetServerPort].GetAsInteger(CT_NetServer_Port);
+    FNode.PeerCache := FAppParams.ParamByName[CT_PARAM_PeerCache].GetAsString('')+';'+CT_Discover_IPs;
     // Check Database
     // Check Database
     FNode.Bank.StorageClass := TDBStorage;
     FNode.Bank.StorageClass := TDBStorage;
-    TDBStorage(FNode.Bank.Storage).AccessFileName := TFolderHelper.GetPascalCoinDataFolder+'\pascalcoin.mdb';
+    TDBStorage(FNode.Bank.Storage).AccessFileName := TFolderHelper.GetPascalCoinDataFolder+'\pascalcoinB03.mdb';
     // Init Grid
     // Init Grid
     FAccountsGrid.Node := FNode;
     FAccountsGrid.Node := FNode;
     FWalletKeys.OnChanged := OnWalletChanged;
     FWalletKeys.OnChanged := OnWalletChanged;
@@ -296,7 +299,7 @@ begin
     FBlockChainDBGrid.AdoConnection := TDBStorage(FNode.Bank.Storage).ADOConnection;
     FBlockChainDBGrid.AdoConnection := TDBStorage(FNode.Bank.Storage).ADOConnection;
     FBlockChainDBGrid.DBGrid := dbGridBlockChain;
     FBlockChainDBGrid.DBGrid := dbGridBlockChain;
     // Init TNode
     // Init TNode
-    TNetData.NetData.OnReceivedHelloResponse := OnReceivedHelloResponse;
+    TNetData.NetData.OnReceivedHelloMessage := OnReceivedHelloMessage;
     TNetData.NetData.OnStatisticsChanged := OnNetStatisticsChanged;
     TNetData.NetData.OnStatisticsChanged := OnNetStatisticsChanged;
     TNetData.NetData.OnNetConnectionsUpdated := onNetConnectionsUpdated;
     TNetData.NetData.OnNetConnectionsUpdated := onNetConnectionsUpdated;
     TNetData.NetData.OnNodeServersUpdated := OnNetNodeServersUpdated;
     TNetData.NetData.OnNodeServersUpdated := OnNetNodeServersUpdated;
@@ -360,7 +363,7 @@ begin
     for i := 0 to lbNetConnections.Items.Count - 1 do begin
     for i := 0 to lbNetConnections.Items.Count - 1 do begin
       if lbNetConnections.Selected[i] then begin
       if lbNetConnections.Selected[i] then begin
         nc := TNetConnection(lbNetconnections.Items.Objects[i]);
         nc := TNetConnection(lbNetconnections.Items.Objects[i]);
-        if TNetData.NetData.ConnectionExists(nc) then begin
+        if TNetData.NetData.ConnectionExistsAndActive(nc) then begin
           FNode.SendNodeMessage(nc,m,errors);
           FNode.SendNodeMessage(nc,m,errors);
           memoMessages.Lines.Add(DateTimeToStr(now)+' Sent to '+nc.Client.RemoteHost+':'+nc.Client.RemotePort+' > '+m);
           memoMessages.Lines.Add(DateTimeToStr(now)+' Sent to '+nc.Client.RemoteHost+':'+nc.Client.RemotePort+' > '+m);
         end;
         end;
@@ -368,7 +371,7 @@ begin
     end;
     end;
   end else begin
   end else begin
     nc := TNetConnection(lbNetconnections.Items.Objects[lbNetconnections.ItemIndex]);
     nc := TNetConnection(lbNetconnections.Items.Objects[lbNetconnections.ItemIndex]);
-    if TNetData.NetData.ConnectionExists(nc) then begin
+    if TNetData.NetData.ConnectionExistsAndActive(nc) then begin
       FNode.SendNodeMessage(nc,m,errors);
       FNode.SendNodeMessage(nc,m,errors);
       memoMessages.Lines.Add(DateTimeToStr(now)+' Sent to '+nc.Client.RemoteHost+':'+nc.Client.RemotePort+' > '+m);
       memoMessages.Lines.Add(DateTimeToStr(now)+' Sent to '+nc.Client.RemoteHost+':'+nc.Client.RemotePort+' > '+m);
     end;
     end;
@@ -440,9 +443,12 @@ procedure TFRMWallet.CheckMining;
   begin
   begin
     if ForceMining then exit;
     if ForceMining then exit;
     // Stop mining
     // Stop mining
-    mtl := FNode.MinerThreads.LockList('TFRMWallet.CheckMining stop');
+    mtl := FNode.MinerThreads.LockList;
     try
     try
       for i:=mtl.Count-1 downto 0 do begin
       for i:=mtl.Count-1 downto 0 do begin
+        if Not TMinerThread(mtl[i]).Paused then begin
+          TLog.NewLog(ltinfo,ClassName,'Stoping miner');
+        end;
         TMinerThread(mtl[i]).Paused := true;
         TMinerThread(mtl[i]).Paused := true;
       end;
       end;
     finally
     finally
@@ -465,10 +471,13 @@ begin
     ) then begin
     ) then begin
     if (cbAllowMining.checked) Or (ForceMining) then begin
     if (cbAllowMining.checked) Or (ForceMining) then begin
       n := 0;
       n := 0;
-      mtl := FNode.MinerThreads.LockList('TFRMWallet.CheckMining base');
+      mtl := FNode.MinerThreads.LockList;
       try
       try
         for i:=mtl.Count-1 downto 0 do begin
         for i:=mtl.Count-1 downto 0 do begin
-          if TMinerThread(mtl[i]).Paused then TMinerThread(mtl[i]).Paused := false;
+          if TMinerThread(mtl[i]).Paused then begin
+            TMinerThread(mtl[i]).Paused := false;
+            TLog.NewLog(ltinfo,ClassName,'Starting miner');
+          end;
           inc(n);
           inc(n);
         end;
         end;
         if n<FMaxCPUs then begin
         if n<FMaxCPUs then begin
@@ -586,6 +595,31 @@ begin
   if key=#13 then  ebFilterOperationsAccountExit(Nil);
   if key=#13 then  ebFilterOperationsAccountExit(Nil);
 end;
 end;
 
 
+procedure TFRMWallet.ebFindAccountNumberChange(Sender: TObject);
+Var an : Cardinal;
+begin
+  if Trim(ebFindAccountNumber.Text)='' then begin
+    ebFindAccountNumber.Color := clWindow;
+    ebFindAccountNumber.Font.Color := clDkGray;
+  end else if TAccountComp.AccountTxtNumberToAccountNumber(ebFindAccountNumber.Text,an) then begin
+    ebFindAccountNumber.Color := clWindow;
+    if FAccountsGrid.MoveRowToAccount(an) then begin
+      ebFindAccountNumber.Font.Color := clWindowText;
+    end else begin
+      ebFindAccountNumber.Font.Color := clRed;
+    end;
+  end else begin
+    // Invalid value
+    ebFindAccountNumber.Color := clRed;
+    ebFindAccountNumber.Font.Color := clWindowText;
+  end;
+end;
+
+procedure TFRMWallet.ebFindAccountNumberExit(Sender: TObject);
+begin
+  ebFindAccountNumber.Text := '';
+end;
+
 function TFRMWallet.ForceMining: Boolean;
 function TFRMWallet.ForceMining: Boolean;
 begin
 begin
   Result := false;
   Result := false;
@@ -593,14 +627,12 @@ end;
 
 
 procedure TFRMWallet.FormCreate(Sender: TObject);
 procedure TFRMWallet.FormCreate(Sender: TObject);
 Var i : Integer;
 Var i : Integer;
+  fvi : TFileVersionInfo;
 begin
 begin
   if CPUCount>1 then FMaxCPUs := CPUCount-1
   if CPUCount>1 then FMaxCPUs := CPUCount-1
   else FMaxCPUs := 1;
   else FMaxCPUs := 1;
   FMessagesUnreadCount := 0;
   FMessagesUnreadCount := 0;
   lblReceivedMessages.Visible := false;
   lblReceivedMessages.Visible := false;
-  FMemoNetConnections := TStringListAux.Create;
-  FMemoBlackListNodes := TStringListAux.Create;
-  FMemoAvailableNodeServers := TStringListAux.Create;
   memoNetConnections.Lines.Clear;
   memoNetConnections.Lines.Clear;
   memoNetServers.Lines.Clear;
   memoNetServers.Lines.Clear;
   memoNetBlackLists.Lines.Clear;
   memoNetBlackLists.Lines.Clear;
@@ -657,6 +689,8 @@ begin
     'Double click the system tray icon to restore Pascal Coin';
     'Double click the system tray icon to restore Pascal Coin';
   TrayIcon.BalloonFlags := bfInfo;
   TrayIcon.BalloonFlags := bfInfo;
   MinersBlocksFound := 0;
   MinersBlocksFound := 0;
+  fvi := TFolderHelper.GetTFileVersionInfo(Application.ExeName);
+  lblBuild.Caption := 'Build: '+fvi.FileVersion;
 end;
 end;
 
 
 procedure TFRMWallet.FormDestroy(Sender: TObject);
 procedure TFRMWallet.FormDestroy(Sender: TObject);
@@ -675,7 +709,7 @@ begin
   FOperationsGrid.Node := Nil;
   FOperationsGrid.Node := Nil;
   FPendingOperationsGrid.Node := Nil;
   FPendingOperationsGrid.Node := Nil;
   FAccountsGrid.Node := Nil;
   FAccountsGrid.Node := Nil;
-  TNetData.NetData.OnReceivedHelloResponse := Nil;
+  TNetData.NetData.OnReceivedHelloMessage := Nil;
   TNetData.NetData.OnStatisticsChanged := Nil;
   TNetData.NetData.OnStatisticsChanged := Nil;
   TNetData.NetData.OnNetConnectionsUpdated := Nil;
   TNetData.NetData.OnNetConnectionsUpdated := Nil;
   TNetData.NetData.OnNodeServersUpdated := Nil;
   TNetData.NetData.OnNodeServersUpdated := Nil;
@@ -697,7 +731,7 @@ begin
   FNodeNotifyEvents.Free;
   FNodeNotifyEvents.Free;
   //
   //
   step := 'Assigning Nil to TNetData';
   step := 'Assigning Nil to TNetData';
-  TNetData.NetData.OnReceivedHelloResponse := Nil;
+  TNetData.NetData.OnReceivedHelloMessage := Nil;
   TNetData.NetData.OnStatisticsChanged := Nil;
   TNetData.NetData.OnStatisticsChanged := Nil;
 
 
   step := 'Destroying grids operators';
   step := 'Destroying grids operators';
@@ -723,9 +757,6 @@ begin
   step := 'Processing messages 2';
   step := 'Processing messages 2';
   Application.ProcessMessages;
   Application.ProcessMessages;
   step := 'Destroying stringslist';
   step := 'Destroying stringslist';
-  FMemoNetConnections.Free;
-  FMemoBlackListNodes.Free;
-  FMemoAvailableNodeServers.Free;
   Except
   Except
     On E:Exception do begin
     On E:Exception do begin
       TLog.NewLog(lterror,Classname,'Error destroying Form step: '+step+' Errors ('+E.ClassName+'): ' +E.Message);
       TLog.NewLog(lterror,Classname,'Error destroying Form step: '+step+' Errors ('+E.ClassName+'): ' +E.Message);
@@ -878,9 +909,9 @@ Var i,j : integer;
  l : TList;
  l : TList;
  strings : TStrings;
  strings : TStrings;
 begin
 begin
-  l := TNetData.NetData.BlackList.LockList('TFRMWallet.OnNetBlackListUpdated');
+  l := TNetData.NetData.BlackList.LockList;
   try
   try
-    strings := FMemoBlackListNodes;
+    strings := memoNetBlackLists.Lines;
     strings.BeginUpdate;
     strings.BeginUpdate;
     Try
     Try
       strings.Clear;
       strings.Clear;
@@ -910,11 +941,12 @@ Const CT_BooleanToString : Array[Boolean] of String = ('False','True');
 Var i : integer;
 Var i : integer;
  NC : TNetConnection;
  NC : TNetConnection;
  l : TList;
  l : TList;
+ sClientApp : String;
  strings, sNSC, sRS, sDisc : TStrings;
  strings, sNSC, sRS, sDisc : TStrings;
 begin
 begin
-  l := TNetData.NetData.NetConnections.LockList('TFRMWallet.OnNetConnectionsUpdated');
+  l := TNetData.NetData.NetConnections.LockList;
   try
   try
-    strings := FMemoNetConnections;
+    strings := memoNetConnections.Lines;
     sNSC := TStringList.Create;
     sNSC := TStringList.Create;
     sRS := TStringList.Create;
     sRS := TStringList.Create;
     sDisc := TStringList.Create;
     sDisc := TStringList.Create;
@@ -922,16 +954,19 @@ begin
     Try
     Try
       for i := 0 to l.Count - 1 do begin
       for i := 0 to l.Count - 1 do begin
         NC := l[i];
         NC := l[i];
+        if (NC.ClientAppVersion='') then sClientApp:='(old version)'
+        else sClientApp := 'Version:'+NC.ClientAppVersion;
+
         if NC.Connected then begin
         if NC.Connected then begin
           if NC is TNetServerClient then begin
           if NC is TNetServerClient then begin
-            sNSC.Add(Format('Client: IP:%s:%s Sent/Received:%d/%d Bytes - Active since %s',
-              [NC.Client.RemoteHost,NC.Client.RemotePort,NC.Client.BytesSent,NC.Client.BytesReceived,DateTimeElapsedTime(NC.CreatedTime)]));
+            sNSC.Add(Format('Client: IP:%s:%s Sent/Received:%d/%d Bytes - %s - Active since %s',
+              [NC.Client.RemoteHost,NC.Client.RemotePort,NC.Client.BytesSent,NC.Client.BytesReceived,sClientApp,DateTimeElapsedTime(NC.CreatedTime)]));
           end else begin
           end else begin
-            if NC.IsMyselfServer then sNSC.Add(Format('MySelf IP:%s:%s Sent/Received:%d/%d Bytes - Active since %s',
-              [NC.Client.RemoteHost,NC.Client.RemotePort,NC.Client.BytesSent,NC.Client.BytesReceived,DateTimeElapsedTime(NC.CreatedTime)]))
+            if NC.IsMyselfServer then sNSC.Add(Format('MySelf IP:%s:%s Sent/Received:%d/%d Bytes - %s - Active since %s',
+              [NC.Client.RemoteHost,NC.Client.RemotePort,NC.Client.BytesSent,NC.Client.BytesReceived,sClientApp,DateTimeElapsedTime(NC.CreatedTime)]))
             else begin
             else begin
-              sRS.Add(Format('Remote Server: IP:%s:%s Sent/Received:%d/%d Bytes - Active since %s',
-              [NC.Client.RemoteHost,NC.Client.RemotePort,NC.Client.BytesSent,NC.Client.BytesReceived,DateTimeElapsedTime(NC.CreatedTime)]));
+              sRS.Add(Format('Remote Server: IP:%s:%s Sent/Received:%d/%d Bytes - %s - Active since %s',
+              [NC.Client.RemoteHost,NC.Client.RemotePort,NC.Client.BytesSent,NC.Client.BytesReceived,sClientApp,DateTimeElapsedTime(NC.CreatedTime)]));
             end;
             end;
           end;
           end;
         end else begin
         end else begin
@@ -972,9 +1007,9 @@ Var i : integer;
  strings : TStrings;
  strings : TStrings;
  s : String;
  s : String;
 begin
 begin
-  l := TNetData.NetData.NodeServers.LockList('TFRMWallet.OnNetNodeServersUpdated');
+  l := TNetData.NetData.NodeServers.LockList;
   try
   try
-    strings := FMemoAvailableNodeServers;
+    strings := memoNetServers.Lines;
     strings.BeginUpdate;
     strings.BeginUpdate;
     Try
     Try
       strings.Clear;
       strings.Clear;
@@ -1014,8 +1049,8 @@ begin
       StatusBar.Panels[0].Text := 'Active (Port '+Inttostr(FNode.NetServer.Port)+')';
       StatusBar.Panels[0].Text := 'Active (Port '+Inttostr(FNode.NetServer.Port)+')';
     end else StatusBar.Panels[0].Text := 'Server stopped';
     end else StatusBar.Panels[0].Text := 'Server stopped';
     NS := TNetData.NetData.NetStatistics;
     NS := TNetData.NetData.NetStatistics;
-    StatusBar.Panels[1].Text := Format('Connections:%d (%d) Clients:%d Servers:%d - Rcvd:%d Bytes Send:%d Bytes',
-      [NS.ActiveConnections,NS.TotalConnections,NS.ClientsConnections,NS.ServersConnections,NS.BytesReceived,NS.BytesSend]);
+    StatusBar.Panels[1].Text := Format('Connections:%d Clients:%d Servers:%d - Rcvd:%d Bytes Send:%d Bytes',
+      [NS.ActiveConnections,NS.ClientsConnections,NS.ServersConnections,NS.BytesReceived,NS.BytesSend]);
   end else begin
   end else begin
     StatusBar.Panels[0].Text := '';
     StatusBar.Panels[0].Text := '';
     StatusBar.Panels[1].Text := '';
     StatusBar.Panels[1].Text := '';
@@ -1050,28 +1085,44 @@ procedure TFRMWallet.OnNodeMessageEvent(NetConnection: TNetConnection; MessageDa
 Var s : String;
 Var s : String;
 begin
 begin
   inc(FMessagesUnreadCount);
   inc(FMessagesUnreadCount);
-  s := DateTimeToStr(now)+' Message received from '+NetConnection.Client.RemoteHost+':'+NetConnection.Client.RemotePort;
-  memoMessages.Lines.Add(DateTimeToStr(now)+' Message received from '+NetConnection.Client.RemoteHost+':'+NetConnection.Client.RemotePort+' Length '+inttostr(Length(MessageData))+' bytes');
-  memoMessages.Lines.Add('RECEIVED> '+MessageData);
-  if FAppParams.ParamByName[CT_PARAM_ShowModalMessages].GetAsBoolean(false) then begin
-    s := DateTimeToStr(now)+' Message from '+NetConnection.Client.RemoteHost+':'+NetConnection.Client.RemotePort+#10+
-       'Length '+inttostr(length(MessageData))+' bytes'+#10+#10;
-    if TCrypto.IsHumanReadable(MessageData) then begin
-       s := s + MessageData;
-    end else begin
-       s := s +'Value in hexadecimal:'+#10+
-            TCrypto.ToHexaString(MessageData);
+  if Assigned(NetConnection) then begin
+    s := DateTimeToStr(now)+' Message received from '+NetConnection.Client.RemoteHost+':'+NetConnection.Client.RemotePort;
+    memoMessages.Lines.Add(DateTimeToStr(now)+' Message received from '+NetConnection.Client.RemoteHost+':'+NetConnection.Client.RemotePort+' Length '+inttostr(Length(MessageData))+' bytes');
+    memoMessages.Lines.Add('RECEIVED> '+MessageData);
+    if FAppParams.ParamByName[CT_PARAM_ShowModalMessages].GetAsBoolean(false) then begin
+      s := DateTimeToStr(now)+' Message from '+NetConnection.Client.RemoteHost+':'+NetConnection.Client.RemotePort+#10+
+         'Length '+inttostr(length(MessageData))+' bytes'+#10+#10;
+      if TCrypto.IsHumanReadable(MessageData) then begin
+         s := s + MessageData;
+      end else begin
+         s := s +'Value in hexadecimal:'+#10+
+              TCrypto.ToHexaString(MessageData);
+      end;
+      Application.MessageBox(PChar(s),PChar(Application.Title),MB_ICONINFORMATION+MB_OK);
     end;
     end;
-    Application.MessageBox(PChar(s),PChar(Application.Title),MB_ICONINFORMATION+MB_OK);
+  end else begin
+    memoMessages.Lines.Add(DateTimeToStr(now)+' Internal message: '+MessageData);
   end;
   end;
   if FMessagesUnreadCount>1 then lblReceivedMessages.Caption := Format('You have received %d messages',[FMessagesUnreadCount])
   if FMessagesUnreadCount>1 then lblReceivedMessages.Caption := Format('You have received %d messages',[FMessagesUnreadCount])
   else lblReceivedMessages.Caption := 'You have received 1 message';
   else lblReceivedMessages.Caption := 'You have received 1 message';
   lblReceivedMessages.Visible := true;
   lblReceivedMessages.Visible := true;
 end;
 end;
 
 
-procedure TFRMWallet.OnReceivedHelloResponse(Sender: TObject);
+procedure TFRMWallet.OnReceivedHelloMessage(Sender: TObject);
+Var nsarr : TNodeServerAddressArray;
+  i : Integer;
+  s : AnsiString;
 begin
 begin
   CheckMining;
   CheckMining;
+  // Update node servers Peer Cache
+  nsarr := TNetData.NetData.GetValidNodeServers;
+  s := '';
+  for i := low(nsarr) to High(nsarr) do begin
+    if (s<>'') then s := s+';';
+    s := s + nsarr[i].ip+':'+IntToStr( nsarr[i].port );
+  end;
+  FAppParams.ParamByName[CT_PARAM_PeerCache].SetAsString(s);
+  TNode.Node.PeerCache := s;
 end;
 end;
 
 
 procedure TFRMWallet.OnWalletChanged(Sender: TObject);
 procedure TFRMWallet.OnWalletChanged(Sender: TObject);
@@ -1133,18 +1184,6 @@ begin
     UpdateConnectionStatus;
     UpdateConnectionStatus;
     UpdateBlockChainState;
     UpdateBlockChainState;
     UpdateNodeStatus;
     UpdateNodeStatus;
-    If (FMemoNetConnections.UpdateCount=0) And (FMemoNetConnections.Count>0) then begin
-      memoNetConnections.Lines.Assign(FMemoNetConnections);
-      FMemoNetConnections.Clear;
-    end;
-    If (FMemoAvailableNodeServers.UpdateCount=0) And (FMemoAvailableNodeServers.Count>0) then begin
-      memoNetServers.Lines.Assign(FMemoAvailableNodeServers);
-      FMemoAvailableNodeServers.Clear;
-    end;
-    If (FMemoBlackListNodes.UpdateCount=0) And (FMemoBlackListNodes.Count>0) then begin
-      memoNetBlackLists.Lines.Assign(FMemoBlackListNodes);
-      FMemoBlackListNodes.Clear;
-    end;
   Except
   Except
     On E:Exception do begin
     On E:Exception do begin
       E.Message := 'Exception at TimerUpdate '+E.ClassName+': '+E.Message;
       E.Message := 'Exception at TimerUpdate '+E.ClassName+': '+E.Message;
@@ -1211,7 +1250,7 @@ Var i : integer;
  NC : TNetConnection;
  NC : TNetConnection;
  l : TList;
  l : TList;
 begin
 begin
-  l := TNetData.NetData.NetConnections.LockList('TFRMWallet.UpdateAvailableConnections');
+  l := TNetData.NetData.NetConnections.LockList;
   try
   try
     lbNetConnections.Items.BeginUpdate;
     lbNetConnections.Items.BeginUpdate;
     Try
     Try
@@ -1267,7 +1306,7 @@ begin
         CT_CalcNewTargetBlocksAverage * 2 ,FormatFloat('0.0',FNode.Bank.GetActualTargetSecondsAverage(CT_CalcNewTargetBlocksAverage * 2)),
         CT_CalcNewTargetBlocksAverage * 2 ,FormatFloat('0.0',FNode.Bank.GetActualTargetSecondsAverage(CT_CalcNewTargetBlocksAverage * 2)),
         CT_CalcNewTargetBlocksAverage DIV 2,FormatFloat('0.0',FNode.Bank.GetActualTargetSecondsAverage(CT_CalcNewTargetBlocksAverage DIV 2)),
         CT_CalcNewTargetBlocksAverage DIV 2,FormatFloat('0.0',FNode.Bank.GetActualTargetSecondsAverage(CT_CalcNewTargetBlocksAverage DIV 2)),
         CT_CalcNewTargetBlocksAverage DIV 4,FormatFloat('0.0',FNode.Bank.GetActualTargetSecondsAverage(CT_CalcNewTargetBlocksAverage DIV 4))]);
         CT_CalcNewTargetBlocksAverage DIV 4,FormatFloat('0.0',FNode.Bank.GetActualTargetSecondsAverage(CT_CalcNewTargetBlocksAverage DIV 4))]);
-    mtl := FNode.MinerThreads.LockList('TFRMWallet.UpdateBlockChainState');
+    mtl := FNode.MinerThreads.LockList;
     try
     try
       mc := mtl.Count;
       mc := mtl.Count;
       If mc>0 then begin
       If mc>0 then begin
@@ -1312,7 +1351,8 @@ begin
     if PageControl.ActivePage = tsLogs then PageControl.ActivePage := tsAccountsExplorer;
     if PageControl.ActivePage = tsLogs then PageControl.ActivePage := tsAccountsExplorer;
   end else FLog.OnNewLog := OnNewLog;
   end else FLog.OnNewLog := OnNewLog;
   if FAppParams.ParamByName[CT_PARAM_SaveLogFiles].GetAsBoolean(false) then begin
   if FAppParams.ParamByName[CT_PARAM_SaveLogFiles].GetAsBoolean(false) then begin
-    FLog.SaveTypes := CT_TLogTypes_DEFAULT;
+    if FAppParams.ParamByName[CT_PARAM_SaveDebugLogs].GetAsBoolean(false) then FLog.SaveTypes := CT_TLogTypes_ALL
+    else FLog.SaveTypes := CT_TLogTypes_DEFAULT;
     FLog.FileName := TFolderHelper.GetPascalCoinDataFolder+'\PascalCointWallet.log';
     FLog.FileName := TFolderHelper.GetPascalCoinDataFolder+'\PascalCointWallet.log';
   end else begin
   end else begin
     FLog.SaveTypes := [];
     FLog.SaveTypes := [];

+ 7 - 1
Units/PascalCoin/UAccounts.pas

@@ -60,6 +60,12 @@ Type
   end;
   end;
   PBlockAccount = ^TBlockAccount;
   PBlockAccount = ^TBlockAccount;
 
 
+  { Estimated TAccount size:
+    4 + 200 (max aprox) + 8 + 4 + 4 = 220 max aprox
+    Estimated TBlockAccount size:
+    4 + (5 * 220) + 4 + 32 = 1140 max aprox
+  }
+
   TPCSafeBox = Class;
   TPCSafeBox = Class;
 
 
   // This is a class to quickly find accountkeys and their respective account number/s
   // This is a class to quickly find accountkeys and their respective account number/s
@@ -851,7 +857,7 @@ begin
     TLog.NewLog(lterror,Classname,'IS LOCKED !!!');
     TLog.NewLog(lterror,Classname,'IS LOCKED !!!');
     raise Exception.Create('IS LOCKED !!!');
     raise Exception.Create('IS LOCKED !!!');
   end;
   end;
-  TPCThread.ProtectEnterCriticalSection(Self,'StartThreadSafe',FLock);
+  TPCThread.ProtectEnterCriticalSection(Self,FLock);
   FIsLocked := true;
   FIsLocked := true;
 end;
 end;
 
 

+ 46 - 14
Units/PascalCoin/UBlockChain.pas

@@ -338,7 +338,7 @@ Var
   buffer, pow: AnsiString;
   buffer, pow: AnsiString;
   i : Integer;
   i : Integer;
 begin
 begin
-  TPCThread.ProtectEnterCriticalSection(Self,'AddNewBlockChainBlock',FBankLock);
+  TPCThread.ProtectEnterCriticalSection(Self,FBankLock);
   Try
   Try
     Result := False;
     Result := False;
     errors := '';
     errors := '';
@@ -517,7 +517,7 @@ begin
     TLog.NewLog(lterror,Classname,'Is Restoring!!!');
     TLog.NewLog(lterror,Classname,'Is Restoring!!!');
     raise Exception.Create('Is restoring!');
     raise Exception.Create('Is restoring!');
   end;
   end;
-  TPCThread.ProtectEnterCriticalSection(Self,'DiskRestoreFromOperations',FBankLock);
+  TPCThread.ProtectEnterCriticalSection(Self,FBankLock);
   try
   try
     FIsRestoringFromFile := true;
     FIsRestoringFromFile := true;
     try
     try
@@ -706,7 +706,7 @@ begin
   Clear;
   Clear;
   Result := SafeBox.LoadFromStream(Stream,LastReadBlock,errors);
   Result := SafeBox.LoadFromStream(Stream,LastReadBlock,errors);
   if Result then begin
   if Result then begin
-    TPCThread.ProtectEnterCriticalSection(Self,'LoadFromStream',FBankLock);
+    TPCThread.ProtectEnterCriticalSection(Self,FBankLock);
     try
     try
       op := TPCOperationsComp.Create(Self);
       op := TPCOperationsComp.Create(Self);
       try
       try
@@ -736,7 +736,7 @@ end;
 
 
 function TPCBank.LoadOperations(Operations: TPCOperationsComp; Block: Cardinal): Boolean;
 function TPCBank.LoadOperations(Operations: TPCOperationsComp; Block: Cardinal): Boolean;
 begin
 begin
-  TPCThread.ProtectEnterCriticalSection(Self,'LoadOperations',FBankLock);
+  TPCThread.ProtectEnterCriticalSection(Self,FBankLock);
   try
   try
     Result := Storage.LoadBlockChainBlock(Operations,Block);
     Result := Storage.LoadBlockChainBlock(Operations,Block);
   finally
   finally
@@ -940,12 +940,12 @@ end;
 
 
 procedure TPCOperationsComp.Calc_Digest_Operations;
 procedure TPCOperationsComp.Calc_Digest_Operations;
 var ms : TMemoryStream;
 var ms : TMemoryStream;
-  i: Cardinal;
   buff: AnsiString;
   buff: AnsiString;
 begin
 begin
   ms := TMemoryStream.Create;
   ms := TMemoryStream.Create;
   try
   try
     ms.WriteBuffer(FOperationsHashTree.HashTree[1],length(FOperationsHashTree.HashTree));
     ms.WriteBuffer(FOperationsHashTree.HashTree[1],length(FOperationsHashTree.HashTree));
+    // Note about fee: Fee is stored in 8 bytes, but only digest first 4 low bytes
     ms.Write(FOperationBlock.fee,4);
     ms.Write(FOperationBlock.fee,4);
     SetLength(FDigest_Operations,ms.Size);
     SetLength(FDigest_Operations,ms.Size);
     ms.Position := 0;
     ms.Position := 0;
@@ -1103,7 +1103,19 @@ end;
 
 
 function TPCOperationsComp.IncrementNOnce: Boolean;
 function TPCOperationsComp.IncrementNOnce: Boolean;
 begin
 begin
-  nonce := nonce + 1;
+  // Important note:
+  // In Build version 1.0.0 to 1.0.2 of PascalCoin the wallet stored nOnce data in an
+  // Access database as an Integer.
+  // There is a limitation of int values in Access that they can't be greater
+  // than MAXINT, so to preventing miners to fall only mines within nonce 0..MaxInt
+  // This limitation is not in the protocol, so in future versions of
+  // PascalCoin nonce can be a full unsigned 4 bytes value.
+  // Note: Build 1.0.3 corrects this issue storing nOnce as a String, but
+  // to prevent old miners working on a fork, for now applying MaxInt
+  // Starting at build (1.0.4) MaxInt will be a full unsigned 4 bytes value.
+  if nonce<MaxInt then
+    nonce := nonce + 1
+  else nonce := 0;
   Result := FOperationBlock.proof_of_work < FBank.FActualTargetHash;
   Result := FOperationBlock.proof_of_work < FBank.FActualTargetHash;
 end;
 end;
 
 
@@ -1171,7 +1183,7 @@ begin
   Stream.Read(FOperationBlock.block, Sizeof(FOperationBlock.block));
   Stream.Read(FOperationBlock.block, Sizeof(FOperationBlock.block));
 
 
   if TStreamOp.ReadAnsiString(Stream, m) < 0 then exit;
   if TStreamOp.ReadAnsiString(Stream, m) < 0 then exit;
-  FOperationBlock.account_key := TAccountComp.RawString2Accountkey(m); // String2Addresskey(m);
+  FOperationBlock.account_key := TAccountComp.RawString2Accountkey(m);
   if Stream.Read(FOperationBlock.reward, Sizeof(FOperationBlock.reward)) < 0 then exit;
   if Stream.Read(FOperationBlock.reward, Sizeof(FOperationBlock.reward)) < 0 then exit;
   if Stream.Read(FOperationBlock.fee, Sizeof(FOperationBlock.fee)) < 0 then exit;
   if Stream.Read(FOperationBlock.fee, Sizeof(FOperationBlock.fee)) < 0 then exit;
   if Stream.Read(FOperationBlock.timestamp, Sizeof(FOperationBlock.timestamp)) < 0 then exit;
   if Stream.Read(FOperationBlock.timestamp, Sizeof(FOperationBlock.timestamp)) < 0 then exit;
@@ -1391,9 +1403,16 @@ begin
 end;
 end;
 
 
 procedure TPCOperationsComp.SetBlockPayload(const Value: TRawBytes);
 procedure TPCOperationsComp.SetBlockPayload(const Value: TRawBytes);
+Var i : Integer;
 begin
 begin
   if Value=FOperationBlock.block_payload then exit;
   if Value=FOperationBlock.block_payload then exit;
   if Length(Value)>CT_MaxPayloadSize then Exit;
   if Length(Value)>CT_MaxPayloadSize then Exit;
+  // Checking Miner Payload valid chars
+  for i := 1 to length(Value) do begin
+    if Not (Value[i] in [#32..#254]) then begin
+      exit;
+    end;
+  end;
   FOperationBlock.block_payload := Value;
   FOperationBlock.block_payload := Value;
   CalcProofOfWork(true,FOperationBlock.proof_of_work);
   CalcProofOfWork(true,FOperationBlock.proof_of_work);
 end;
 end;
@@ -1435,6 +1454,19 @@ begin
       exit;
       exit;
     end;
     end;
   end;
   end;
+  // Checking Miner payload size
+  if length(BlockPayload)>CT_MaxPayloadSize then begin
+    errors := 'Invalid Miner Payload length: '+inttostr(Length(BlockPayload));
+    exit;
+  end;
+  // Checking Miner Payload valid chars
+  for i := 1 to length(BlockPayload) do begin
+    if Not (BlockPayload[i] in [#32..#254]) then begin
+      errors := 'Invalid Miner Payload character at pos '+inttostr(i)+' value:'+inttostr(ord(BlockPayload[i]));
+      exit;
+    end;
+  end;
+
   CalcProofOfWork(true,FOperationBlock.proof_of_work);
   CalcProofOfWork(true,FOperationBlock.proof_of_work);
   if Not AnsiSameStr(OperationBlock.proof_of_work,lastpow) then begin
   if Not AnsiSameStr(OperationBlock.proof_of_work,lastpow) then begin
     errors := 'Invalid Proof of work calculation';
     errors := 'Invalid Proof of work calculation';
@@ -1509,7 +1541,7 @@ end;
 procedure TOperationsHashTree.AddOperationToHashTree(op: TPCOperation);
 procedure TOperationsHashTree.AddOperationToHashTree(op: TPCOperation);
 Var l : TList;
 Var l : TList;
 begin
 begin
-  l := FHashTreeOperations.LockList('TOperationsHashTree.AddOperationToHashTree');
+  l := FHashTreeOperations.LockList;
   try
   try
     InternalAddOperationToHashTree(l,op);
     InternalAddOperationToHashTree(l,op);
   finally
   finally
@@ -1522,7 +1554,7 @@ var op : TPCOperation;
   l : TList;
   l : TList;
   i : Integer;
   i : Integer;
 begin
 begin
-  l := FHashTreeOperations.LockList('TOperationsHashTree.ClearHastThree');
+  l := FHashTreeOperations.LockList;
   try
   try
     Try
     Try
       for i := 0 to l.Count - 1 do begin
       for i := 0 to l.Count - 1 do begin
@@ -1549,8 +1581,8 @@ begin
   end;
   end;
 
 
   ClearHastThree;
   ClearHastThree;
-  lme := FHashTreeOperations.LockList('TOperationsHashTree.CopyFromHashTree me');
-  lsender := Sender.FHashTreeOperations.LockList('TOperationsHashTree.CopyFromHashTree sender');
+  lme := FHashTreeOperations.LockList;
+  lsender := Sender.FHashTreeOperations.LockList;
   try
   try
     ms := TMemoryStream.Create;
     ms := TMemoryStream.Create;
     Try
     Try
@@ -1588,7 +1620,7 @@ end;
 function TOperationsHashTree.GetOperation(index: Integer): TPCOperation;
 function TOperationsHashTree.GetOperation(index: Integer): TPCOperation;
 Var l : TList;
 Var l : TList;
 begin
 begin
-  l := FHashTreeOperations.LockList('TOperationsHashTree.GetOperation');
+  l := FHashTreeOperations.LockList;
   try
   try
     Result := TPCOperation(l[index]);
     Result := TPCOperation(l[index]);
   finally
   finally
@@ -1602,7 +1634,7 @@ Var l,intl : TList;
   i,j : Integer;
   i,j : Integer;
 begin
 begin
   List.Clear;
   List.Clear;
-  l := FHashTreeOperations.LockList('TOperationsHashTree.GetOperationsAffectingAccount');
+  l := FHashTreeOperations.LockList;
   try
   try
     intl := TList.Create;
     intl := TList.Create;
     try
     try
@@ -1643,7 +1675,7 @@ end;
 function TOperationsHashTree.OperationsCount: Integer;
 function TOperationsHashTree.OperationsCount: Integer;
 Var l : TList;
 Var l : TList;
 begin
 begin
-  l := FHashTreeOperations.LockList('TOperationsHashTree.OperationsCount');
+  l := FHashTreeOperations.LockList;
   try
   try
     Result := l.Count;
     Result := l.Count;
   finally
   finally

+ 2 - 0
Units/PascalCoin/UConst.pas

@@ -69,6 +69,8 @@ Const
   CT_Op_Changekey = $02;
   CT_Op_Changekey = $02;
   CT_Op_Recover = $03;
   CT_Op_Recover = $03;
 
 
+  CT_ClientAppVersion : AnsiString = '1.0.3';
+
   CT_Discover_IPs =  'bpascal1.dynamic-dns.net;bpascal2.dynamic-dns.net;pascalcoin1.ddns.net;pascalcoin2.ddns.net;pascalcoin1.dynamic-dns.net;pascalcoin1.dns1.us';
   CT_Discover_IPs =  'bpascal1.dynamic-dns.net;bpascal2.dynamic-dns.net;pascalcoin1.ddns.net;pascalcoin2.ddns.net;pascalcoin1.dynamic-dns.net;pascalcoin1.dns1.us';
 
 
   CT_TRUE_FALSE : Array[Boolean] Of AnsiString = ('FALSE','TRUE');
   CT_TRUE_FALSE : Array[Boolean] Of AnsiString = ('FALSE','TRUE');

+ 0 - 19
Units/PascalCoin/UCrypto.pas

@@ -65,9 +65,7 @@ Type
     Class function HexaToRaw(const HexaString : AnsiString) : TRawBytes;
     Class function HexaToRaw(const HexaString : AnsiString) : TRawBytes;
     Class function DoSha256(p : PAnsiChar; plength : Cardinal) : TRawBytes; overload;
     Class function DoSha256(p : PAnsiChar; plength : Cardinal) : TRawBytes; overload;
     Class function DoSha256(const TheMessage : AnsiString) : TRawBytes; overload;
     Class function DoSha256(const TheMessage : AnsiString) : TRawBytes; overload;
-    Class function DoDoubleSha256(p : PAnsiChar; plength : Cardinal) : TRawBytes; overload;
     Class procedure DoDoubleSha256(p : PAnsiChar; plength : Cardinal; Var ResultSha256 : TRawBytes); overload;
     Class procedure DoDoubleSha256(p : PAnsiChar; plength : Cardinal; Var ResultSha256 : TRawBytes); overload;
-    Class function DoDoubleSha256(const TheMessage : AnsiString) : TRawBytes; overload;
     Class function DoRipeMD160(const TheMessage : AnsiString) : TRawBytes;
     Class function DoRipeMD160(const TheMessage : AnsiString) : TRawBytes;
     Class function PrivateKey2Hexa(Key : PEC_KEY) : AnsiString;
     Class function PrivateKey2Hexa(Key : PEC_KEY) : AnsiString;
     Class function ECDSASign(Key : PEC_KEY; const digest : AnsiString) : TECDSA_SIG;
     Class function ECDSASign(Key : PEC_KEY; const digest : AnsiString) : TECDSA_SIG;
@@ -315,23 +313,6 @@ end;
 
 
 { TCrypto }
 { TCrypto }
 
 
-class function TCrypto.DoDoubleSha256(const TheMessage: AnsiString): TRawBytes;
-begin
-  Result := DoSha256(DoSha256(TheMessage));
-end;
-
-class function TCrypto.DoDoubleSha256(p: PAnsiChar; plength: Cardinal): TRawBytes;
-Var PS,PS1 : PAnsiChar;
-  PC : PAnsiChar;
-begin
-  SetLength(Result,32);
-  PS := @Result[1];
-  GetMem(PS1,32);
-  SHA256(p,plength,PS1);
-  SHA256(PS1,32,PS);
-  FreeMem(PS1,32);
-end;
-
 { New at Build 1.0.2
 { New at Build 1.0.2
   Note: Delphi is slowly when working with Strings (allowing space)... so to
   Note: Delphi is slowly when working with Strings (allowing space)... so to
   increase speed we use a String as a pointer, and only increase speed if
   increase speed we use a String as a pointer, and only increase speed if

+ 45 - 45
Units/PascalCoin/UDBStorage.pas

@@ -47,13 +47,13 @@ Const
   CT_TblFld_BlockChain_id = 'idblockchain';
   CT_TblFld_BlockChain_id = 'idblockchain';
   CT_TblFld_BlockChain_block = 'block';
   CT_TblFld_BlockChain_block = 'block';
   CT_TblFld_BlockChain_accountkey = 'accountkey';
   CT_TblFld_BlockChain_accountkey = 'accountkey';
-  CT_TblFld_BlockChain_reward = 'reward';
-  CT_TblFld_BlockChain_fee = 'fee';
+  CT_TblFld_BlockChain_s_reward = 's_reward';
+  CT_TblFld_BlockChain_s_fee = 's_fee';
   CT_TblFld_BlockChain_protocol_version = 'protocol_version';
   CT_TblFld_BlockChain_protocol_version = 'protocol_version';
   CT_TblFld_BlockChain_protocol_available = 'protocol_available';
   CT_TblFld_BlockChain_protocol_available = 'protocol_available';
-  CT_TblFld_BlockChain_timestamp = 'timestamp';
-  CT_TblFld_BlockChain_compact_target = 'compact_target';
-  CT_TblFld_BlockChain_nonce = 'nonce';
+  CT_TblFld_BlockChain_s_timestamp = 's_timestamp';
+  CT_TblFld_BlockChain_s_compact_target = 's_compact_target';
+  CT_TblFld_BlockChain_s_nonce = 's_nonce';
   CT_TblFld_BlockChain_rawpayload = 'rawpayload';
   CT_TblFld_BlockChain_rawpayload = 'rawpayload';
   CT_TblFld_BlockChain_safe_box_hash = 'safe_box_hash';
   CT_TblFld_BlockChain_safe_box_hash = 'safe_box_hash';
   CT_TblFld_BlockChain_operations_hash = 'operations_hash';
   CT_TblFld_BlockChain_operations_hash = 'operations_hash';
@@ -65,15 +65,15 @@ Const
   CT_TblFld_Operations_id = 'idoperation';
   CT_TblFld_Operations_id = 'idoperation';
   CT_TblFld_Operations_optype = 'optype';
   CT_TblFld_Operations_optype = 'optype';
   CT_TblFld_Operations_block = 'block';
   CT_TblFld_Operations_block = 'block';
-  CT_TblFld_Operations_timestamp = 'timestamp';
+  CT_TblFld_Operations_s_timestamp = 's_timestamp';
   CT_TblFld_Operations_nopblock = 'nopblock';
   CT_TblFld_Operations_nopblock = 'nopblock';
   CT_TblFld_Operations_account = 'account';
   CT_TblFld_Operations_account = 'account';
   CT_TblFld_Operations_other_account = 'other_account';
   CT_TblFld_Operations_other_account = 'other_account';
   CT_TblFld_Operations_n_operation = 'n_operation';
   CT_TblFld_Operations_n_operation = 'n_operation';
   CT_TblFld_Operations_optype_op = 'optype_op';
   CT_TblFld_Operations_optype_op = 'optype_op';
-  CT_TblFld_Operations_amount = 'amount';
-  CT_TblFld_Operations_fee = 'fee';
-  CT_TblFld_Operations_balance = 'balance';
+  CT_TblFld_Operations_s_amount = 's_amount';
+  CT_TblFld_Operations_s_fee = 's_fee';
+  CT_TblFld_Operations_s_balance = 's_balance';
   CT_TblFld_Operations_rawpayload = 'payload';
   CT_TblFld_Operations_rawpayload = 'payload';
   CT_TblFld_Operations_newaccountkey = 'newaccountkey';
   CT_TblFld_Operations_newaccountkey = 'newaccountkey';
   CT_TblFld_Operations_orphan = 'orphan';
   CT_TblFld_Operations_orphan = 'orphan';
@@ -134,7 +134,7 @@ Type
     Property AccessFileName : AnsiString read FAccessFileName write SetAccessFileName;
     Property AccessFileName : AnsiString read FAccessFileName write SetAccessFileName;
     Function SQL_UPDATE(const TblName : AnsiString; Const SetValue : AnsiString; const Where : String): Boolean;
     Function SQL_UPDATE(const TblName : AnsiString; Const SetValue : AnsiString; const Where : String): Boolean;
     Function SQL_DELETE(const TblName : AnsiString; const Where : String): Boolean;
     Function SQL_DELETE(const TblName : AnsiString; const Where : String): Boolean;
-    Function ValueToSql(const Value : Variant) : String;
+    Class Function ValueToSql(const Value : Variant) : String;
     Procedure CopyConfiguration(Const CopyFrom : TStorage); override;
     Procedure CopyConfiguration(Const CopyFrom : TStorage); override;
     Property ADOConnection : TADOConnection read FAdoConnection;
     Property ADOConnection : TADOConnection read FAdoConnection;
     Class Function DBPayloadToReadableText(Const DBRawPayload : TRawBytes; Var ReadableText : AnsiString) : Boolean;
     Class Function DBPayloadToReadableText(Const DBRawPayload : TRawBytes; Var ReadableText : AnsiString) : Boolean;
@@ -561,13 +561,13 @@ begin
       aux := TCrypto.ToHexaString( TAccountComp.AccountKey2RawString(Operations.OperationBlock.account_key) );
       aux := TCrypto.ToHexaString( TAccountComp.AccountKey2RawString(Operations.OperationBlock.account_key) );
       if (length(aux)>255) then aux := copy(aux,1,252)+'...';
       if (length(aux)>255) then aux := copy(aux,1,252)+'...';
       ds.FieldByName(CT_TblFld_BlockChain_accountkey).Value := Copy(aux,1,255);
       ds.FieldByName(CT_TblFld_BlockChain_accountkey).Value := Copy(aux,1,255);
-      ds.FieldByName(CT_TblFld_BlockChain_reward).Value := Operations.OperationBlock.reward;
-      ds.FieldByName(CT_TblFld_BlockChain_fee).Value := Operations.OperationBlock.fee;
+      ds.FieldByName(CT_TblFld_BlockChain_s_reward).Value := Format('%.18d', [Operations.OperationBlock.reward] );
+      ds.FieldByName(CT_TblFld_BlockChain_s_fee).Value := Format('%.18d', [Operations.OperationBlock.fee] );
       ds.FieldByName(CT_TblFld_BlockChain_protocol_version).Value := Operations.OperationBlock.protocol_version;
       ds.FieldByName(CT_TblFld_BlockChain_protocol_version).Value := Operations.OperationBlock.protocol_version;
       ds.FieldByName(CT_TblFld_BlockChain_protocol_available).Value := Operations.OperationBlock.protocol_available;
       ds.FieldByName(CT_TblFld_BlockChain_protocol_available).Value := Operations.OperationBlock.protocol_available;
-      ds.FieldByName(CT_TblFld_BlockChain_timestamp).Value := Operations.OperationBlock.timestamp;
-      ds.FieldByName(CT_TblFld_BlockChain_compact_target).Value := Operations.OperationBlock.compact_target;
-      ds.FieldByName(CT_TblFld_BlockChain_nonce).Value := Operations.OperationBlock.nonce;
+      ds.FieldByName(CT_TblFld_BlockChain_s_timestamp).Value := Format('%.10d', [Operations.OperationBlock.timestamp] );
+      ds.FieldByName(CT_TblFld_BlockChain_s_compact_target).Value := Format('%.10d', [Operations.OperationBlock.compact_target] );
+      ds.FieldByName(CT_TblFld_BlockChain_s_nonce).Value := Format('%.10d', [Operations.OperationBlock.nonce] );
       DBRawToStringField(ds.FieldByName(CT_TblFld_BlockChain_rawpayload),Operations.OperationBlock.block_payload);
       DBRawToStringField(ds.FieldByName(CT_TblFld_BlockChain_rawpayload),Operations.OperationBlock.block_payload);
       ds.FieldByName(CT_TblFld_BlockChain_safe_box_hash).Value := TCrypto.ToHexaString( Operations.OperationBlock.initial_safe_box_hash );
       ds.FieldByName(CT_TblFld_BlockChain_safe_box_hash).Value := TCrypto.ToHexaString( Operations.OperationBlock.initial_safe_box_hash );
       ds.FieldByName(CT_TblFld_BlockChain_operations_hash).Value := TCrypto.ToHexaString( Operations.OperationBlock.operations_hash );
       ds.FieldByName(CT_TblFld_BlockChain_operations_hash).Value := TCrypto.ToHexaString( Operations.OperationBlock.operations_hash );
@@ -587,16 +587,16 @@ begin
       ds.Insert;
       ds.Insert;
       ds.FieldByName(CT_TblFld_Operations_optype).Value := 0;
       ds.FieldByName(CT_TblFld_Operations_optype).Value := 0;
       ds.FieldByName(CT_TblFld_Operations_block).Value := Operations.OperationBlock.block;
       ds.FieldByName(CT_TblFld_Operations_block).Value := Operations.OperationBlock.block;
-      ds.FieldByName(CT_TblFld_Operations_timestamp).Value := Operations.OperationBlock.timestamp;
+      ds.FieldByName(CT_TblFld_Operations_s_timestamp).Value := Format('%.10d', [Operations.OperationBlock.timestamp] );
       ds.FieldByName(CT_TblFld_Operations_nopblock).Value := -1;
       ds.FieldByName(CT_TblFld_Operations_nopblock).Value := -1;
       ds.FieldByName(CT_TblFld_Operations_optype_op).Value := 0;
       ds.FieldByName(CT_TblFld_Operations_optype_op).Value := 0;
-      ds.FieldByName(CT_TblFld_Operations_fee).Value := 0;
+      ds.FieldByName(CT_TblFld_Operations_s_fee).Value := '0';
       ds.FieldByName(CT_TblFld_Operations_orphan).Value := vOrphan;
       ds.FieldByName(CT_TblFld_Operations_orphan).Value := vOrphan;
       ds.FieldByName(CT_TblFld_Operations_n_operation).Value := 0;
       ds.FieldByName(CT_TblFld_Operations_n_operation).Value := 0;
       ds.FieldByName(CT_TblFld_Operations_account).Value := Operations.OperationBlock.block * CT_AccountsPerBlock;
       ds.FieldByName(CT_TblFld_Operations_account).Value := Operations.OperationBlock.block * CT_AccountsPerBlock;
       ds.FieldByName(CT_TblFld_Operations_other_account).Value := Operations.OperationBlock.block * CT_AccountsPerBlock;
       ds.FieldByName(CT_TblFld_Operations_other_account).Value := Operations.OperationBlock.block * CT_AccountsPerBlock;
-      ds.FieldByName(CT_TblFld_Operations_amount).Value := Operations.OperationBlock.reward+Operations.OperationBlock.fee;
-      ds.FieldByName(CT_TblFld_Operations_balance).Value := Operations.OperationBlock.reward+Operations.OperationBlock.fee;
+      ds.FieldByName(CT_TblFld_Operations_s_amount).Value := Format('%.18d', [Operations.OperationBlock.reward+Operations.OperationBlock.fee] );
+      ds.FieldByName(CT_TblFld_Operations_s_balance).Value := Format('%.18d', [Operations.OperationBlock.reward+Operations.OperationBlock.fee] );
       ds.Post;
       ds.Post;
       // Insert operations
       // Insert operations
       for i := 0 to Operations.Count-1 do begin
       for i := 0 to Operations.Count-1 do begin
@@ -604,42 +604,42 @@ begin
         op := Operations.Operation[i];
         op := Operations.Operation[i];
         ds.FieldByName(CT_TblFld_Operations_optype).Value := op.OpType;
         ds.FieldByName(CT_TblFld_Operations_optype).Value := op.OpType;
         ds.FieldByName(CT_TblFld_Operations_block).Value := Operations.OperationBlock.block;
         ds.FieldByName(CT_TblFld_Operations_block).Value := Operations.OperationBlock.block;
-        ds.FieldByName(CT_TblFld_Operations_timestamp).Value := Operations.OperationBlock.timestamp;
+        ds.FieldByName(CT_TblFld_Operations_s_timestamp).Value := Format('%.10d', [Operations.OperationBlock.timestamp] );
         ds.FieldByName(CT_TblFld_Operations_nopblock).Value := i;
         ds.FieldByName(CT_TblFld_Operations_nopblock).Value := i;
         ds.FieldByName(CT_TblFld_Operations_optype_op).Value := 0;
         ds.FieldByName(CT_TblFld_Operations_optype_op).Value := 0;
-        ds.FieldByName(CT_TblFld_Operations_fee).Value := (-1)*op.OperationFee; // Fee is a Negative number
+        ds.FieldByName(CT_TblFld_Operations_s_fee).Value := Format('%.18d', [(-1)*op.OperationFee] ); // Fee is a Negative number
         ds.FieldByName(CT_TblFld_Operations_orphan).Value := vOrphan;
         ds.FieldByName(CT_TblFld_Operations_orphan).Value := vOrphan;
         case op.OpType of
         case op.OpType of
           CT_Op_Transaction : Begin
           CT_Op_Transaction : Begin
             ds.FieldByName(CT_TblFld_Operations_n_operation).Value := TOpTransaction(op).Data.n_operation;
             ds.FieldByName(CT_TblFld_Operations_n_operation).Value := TOpTransaction(op).Data.n_operation;
             ds.FieldByName(CT_TblFld_Operations_account).Value :=  TOpTransaction(op).Data.sender;
             ds.FieldByName(CT_TblFld_Operations_account).Value :=  TOpTransaction(op).Data.sender;
             ds.FieldByName(CT_TblFld_Operations_other_account).Value :=  TOpTransaction(op).Data.target;
             ds.FieldByName(CT_TblFld_Operations_other_account).Value :=  TOpTransaction(op).Data.target;
-            ds.FieldByName(CT_TblFld_Operations_amount).Value := (-1)*TOpTransaction(op).Data.amount;
+            ds.FieldByName(CT_TblFld_Operations_s_amount).Value := Format('%.18d', [(-1)*TOpTransaction(op).Data.amount] );
             DBRawToStringField(ds.FieldByName(CT_TblFld_Operations_rawpayload),TOpTransaction(op).Data.payload);
             DBRawToStringField(ds.FieldByName(CT_TblFld_Operations_rawpayload),TOpTransaction(op).Data.payload);
-            ds.FieldByName(CT_TblFld_Operations_balance).Value := GetOperationBalance(i,TOpTransaction(op).Data.sender);
+            ds.FieldByName(CT_TblFld_Operations_s_balance).Value := Format('%.18d', [GetOperationBalance(i,TOpTransaction(op).Data.sender)] );
             ds.Post;
             ds.Post;
             ds.Insert;
             ds.Insert;
             ds.FieldByName(CT_TblFld_Operations_optype).Value := op.OpType;
             ds.FieldByName(CT_TblFld_Operations_optype).Value := op.OpType;
             ds.FieldByName(CT_TblFld_Operations_block).Value := Operations.OperationBlock.block;
             ds.FieldByName(CT_TblFld_Operations_block).Value := Operations.OperationBlock.block;
-            ds.FieldByName(CT_TblFld_Operations_timestamp).Value := Operations.OperationBlock.timestamp;
+            ds.FieldByName(CT_TblFld_Operations_s_timestamp).Value := Format('%.10d', [Operations.OperationBlock.timestamp] );
             ds.FieldByName(CT_TblFld_Operations_nopblock).Value := i;
             ds.FieldByName(CT_TblFld_Operations_nopblock).Value := i;
             ds.FieldByName(CT_TblFld_Operations_optype_op).Value := 1; // Receive transaction
             ds.FieldByName(CT_TblFld_Operations_optype_op).Value := 1; // Receive transaction
-            ds.FieldByName(CT_TblFld_Operations_fee).Value := 0;  // No fee for receiver
-            ds.FieldByName(CT_TblFld_Operations_balance).Value := GetOperationBalance(i,TOpTransaction(op).Data.target);
+            ds.FieldByName(CT_TblFld_Operations_s_fee).Value := '0';  // No fee for receiver
+            ds.FieldByName(CT_TblFld_Operations_s_balance).Value := Format('%.18d', [GetOperationBalance(i,TOpTransaction(op).Data.target)] );
             ds.FieldByName(CT_TblFld_Operations_orphan).Value := vOrphan;
             ds.FieldByName(CT_TblFld_Operations_orphan).Value := vOrphan;
             ds.FieldByName(CT_TblFld_Operations_n_operation).Value := 0; // No n_operation for receiver
             ds.FieldByName(CT_TblFld_Operations_n_operation).Value := 0; // No n_operation for receiver
             ds.FieldByName(CT_TblFld_Operations_account).Value :=  TOpTransaction(op).Data.target;
             ds.FieldByName(CT_TblFld_Operations_account).Value :=  TOpTransaction(op).Data.target;
             ds.FieldByName(CT_TblFld_Operations_other_account).Value :=  TOpTransaction(op).Data.sender;
             ds.FieldByName(CT_TblFld_Operations_other_account).Value :=  TOpTransaction(op).Data.sender;
-            ds.FieldByName(CT_TblFld_Operations_amount).Value := TOpTransaction(op).Data.amount;
+            ds.FieldByName(CT_TblFld_Operations_s_amount).Value := Format('%.18d', [TOpTransaction(op).Data.amount] );
             DBRawToStringField(ds.FieldByName(CT_TblFld_Operations_rawpayload),TOpTransaction(op).Data.payload);
             DBRawToStringField(ds.FieldByName(CT_TblFld_Operations_rawpayload),TOpTransaction(op).Data.payload);
             ds.Post;
             ds.Post;
           End;
           End;
           CT_Op_Changekey : Begin
           CT_Op_Changekey : Begin
             ds.FieldByName(CT_TblFld_Operations_n_operation).Value := TOpChangeKey(op).Data.n_operation;
             ds.FieldByName(CT_TblFld_Operations_n_operation).Value := TOpChangeKey(op).Data.n_operation;
             ds.FieldByName(CT_TblFld_Operations_account).Value :=  TOpChangeKey(op).Data.account;
             ds.FieldByName(CT_TblFld_Operations_account).Value :=  TOpChangeKey(op).Data.account;
-            ds.FieldByName(CT_TblFld_Operations_amount).Value := 0;
+            ds.FieldByName(CT_TblFld_Operations_s_amount).Value := '0';
             DBRawToStringField(ds.FieldByName(CT_TblFld_Operations_rawpayload),TOpChangeKey(op).Data.payload);
             DBRawToStringField(ds.FieldByName(CT_TblFld_Operations_rawpayload),TOpChangeKey(op).Data.payload);
-            ds.FieldByName(CT_TblFld_Operations_balance).Value := GetOperationBalance(i,TOpChangeKey(op).Data.account); //Operations.bank.SafeBox.Account( TOpChangeKey(op).Data.account ).balance;
+            ds.FieldByName(CT_TblFld_Operations_s_balance).Value := Format('%.18d', [GetOperationBalance(i,TOpChangeKey(op).Data.account)] );
             aux := TCrypto.ToHexaString( TAccountComp.AccountKey2RawString(TOpChangeKey(op).Data.new_accountkey) );
             aux := TCrypto.ToHexaString( TAccountComp.AccountKey2RawString(TOpChangeKey(op).Data.new_accountkey) );
             if (length(aux)>255) then aux := copy(aux,1,252)+'...';
             if (length(aux)>255) then aux := copy(aux,1,252)+'...';
             ds.FieldByName(CT_TblFld_Operations_newaccountkey).Value := Copy(aux,1,255);
             ds.FieldByName(CT_TblFld_Operations_newaccountkey).Value := Copy(aux,1,255);
@@ -648,8 +648,8 @@ begin
           CT_Op_Recover : Begin
           CT_Op_Recover : Begin
             ds.FieldByName(CT_TblFld_Operations_n_operation).Value := TOpRecoverFounds(op).Data.n_operation;
             ds.FieldByName(CT_TblFld_Operations_n_operation).Value := TOpRecoverFounds(op).Data.n_operation;
             ds.FieldByName(CT_TblFld_Operations_account).Value :=  TOpRecoverFounds(op).Data.account;
             ds.FieldByName(CT_TblFld_Operations_account).Value :=  TOpRecoverFounds(op).Data.account;
-            ds.FieldByName(CT_TblFld_Operations_amount).Value := 0;
-            ds.FieldByName(CT_TblFld_Operations_balance).Value := GetOperationBalance(i,TOpRecoverFounds(op).Data.account); //Operations.bank.SafeBox.Account( TOpRecoverFounds(op).Data.account ).balance;
+            ds.FieldByName(CT_TblFld_Operations_s_amount).Value := '0';
+            ds.FieldByName(CT_TblFld_Operations_s_balance).Value := Format('%.18d', [GetOperationBalance(i,TOpRecoverFounds(op).Data.account)] );
             ds.Post;
             ds.Post;
           End;
           End;
         else raise Exception.Create('Development error: OpType not available to save to the Database '+Inttostr(Op.OpType));
         else raise Exception.Create('Development error: OpType not available to save to the Database '+Inttostr(Op.OpType));
@@ -683,10 +683,10 @@ begin
     where := where + ' AND ('+CT_TblFld_BlockChain_block+'<='+IntToStr(block_end)+')';
     where := where + ' AND ('+CT_TblFld_BlockChain_block+'<='+IntToStr(block_end)+')';
   end;
   end;
   if (dateStart>1000) then begin
   if (dateStart>1000) then begin
-    where := where + ' AND ('+CT_TblFld_BlockChain_timestamp+'>='+IntToStr(UnivDateTimeToUnix(DateTime2UnivDateTime(dateStart)))+')';
+    where := where + ' AND ('+CT_TblFld_BlockChain_s_timestamp+'>='+TDBStorage.ValueToSql(Format('%.10d', [UnivDateTimeToUnix(DateTime2UnivDateTime(dateStart))]))+')';
   end;
   end;
   if (dateEnd>1000) then begin
   if (dateEnd>1000) then begin
-    where := where + ' AND ('+CT_TblFld_BlockChain_timestamp+'<'+IntToStr(UnivDateTimeToUnix(DateTime2UnivDateTime(dateEnd+1)))+')';
+    where := where + ' AND ('+CT_TblFld_BlockChain_s_timestamp+'<'+ValueToSql(Format('%.10d', [UnivDateTimeToUnix(DateTime2UnivDateTime(dateEnd+1))]))+')';
   end;
   end;
 
 
   Result := 'SELECT '+sqltop+' * '+
   Result := 'SELECT '+sqltop+' * '+
@@ -722,7 +722,7 @@ begin
           OPR := CT_TOperationResume_NUL;
           OPR := CT_TOperationResume_NUL;
           OPR.Block := ds.FieldByName(CT_TblFld_Operations_block).AsInteger;
           OPR.Block := ds.FieldByName(CT_TblFld_Operations_block).AsInteger;
           OPR.AffectedAccount := account_number;
           OPR.AffectedAccount := account_number;
-          OPR.time := ds.FieldByName(CT_TblFld_BlockChain_timestamp).AsInteger;
+          OPR.time := StrToIntDef( ds.FieldByName(CT_TblFld_BlockChain_s_timestamp).AsString,0);
           case ds.FieldByName(CT_TblFld_Operations_optype).AsInteger of
           case ds.FieldByName(CT_TblFld_Operations_optype).AsInteger of
             0 : OPR.OperationTxt := 'Blockchain reward';
             0 : OPR.OperationTxt := 'Blockchain reward';
             CT_Op_Transaction : begin
             CT_Op_Transaction : begin
@@ -741,9 +741,9 @@ begin
           else
           else
             OPR.OperationTxt := 'Unknown OpType:'+Inttostr(ds.FieldByName(CT_TblFld_Operations_optype).AsInteger);
             OPR.OperationTxt := 'Unknown OpType:'+Inttostr(ds.FieldByName(CT_TblFld_Operations_optype).AsInteger);
           end;
           end;
-          OPR.Amount := ds.FieldByName(CT_TblFld_Operations_amount).AsLargeInt;
-          OPR.Fee := ds.FieldByName(CT_TblFld_Operations_fee).AsLargeInt;
-          OPR.Balance := ds.FieldByName(CT_TblFld_Operations_balance).AsLargeInt;
+          OPR.Amount := StrToInt64Def( ds.FieldByName(CT_TblFld_Operations_s_amount).AsString ,0 );
+          OPR.Fee := StrToInt64Def( ds.FieldByName(CT_TblFld_Operations_s_fee).AsString ,0);
+          OPR.Balance := StrToInt64Def( ds.FieldByName(CT_TblFld_Operations_s_balance).AsString ,0);
           DBStringFieldToRaw(ds.FieldByName(CT_TblFld_Operations_rawpayload),OPR.OriginalPayload);
           DBStringFieldToRaw(ds.FieldByName(CT_TblFld_Operations_rawpayload),OPR.OriginalPayload);
           If DBPayloadToReadableText(OPR.OriginalPayload,spayload) then OPR.PrintablePayload := spayload
           If DBPayloadToReadableText(OPR.OriginalPayload,spayload) then OPR.PrintablePayload := spayload
           else OPR.PrintablePayload := TCrypto.ToHexaString(OPR.OriginalPayload);
           else OPR.PrintablePayload := TCrypto.ToHexaString(OPR.OriginalPayload);
@@ -777,10 +777,10 @@ begin
     where := where + ' AND ('+CT_TblFld_Operations_block+'<='+IntToStr(block_end)+')';
     where := where + ' AND ('+CT_TblFld_Operations_block+'<='+IntToStr(block_end)+')';
   end;
   end;
   if (dateStart>1000) then begin
   if (dateStart>1000) then begin
-    where := where + ' AND ('+CT_TblFld_Operations_timestamp+'>='+IntToStr(UnivDateTimeToUnix(DateTime2UnivDateTime(dateStart)))+')';
+    where := where + ' AND ('+CT_TblFld_Operations_s_timestamp+'>='+ValueToSql( Format('%.10d', [UnivDateTimeToUnix(DateTime2UnivDateTime(dateStart))]))+')';
   end;
   end;
   if (dateEnd>1000) then begin
   if (dateEnd>1000) then begin
-    where := where + ' AND ('+CT_TblFld_Operations_timestamp+'<'+IntToStr(UnivDateTimeToUnix(DateTime2UnivDateTime(dateEnd+1)))+')';
+    where := where + ' AND ('+CT_TblFld_Operations_s_timestamp+'<'+ValueToSql( Format('%.10d', [UnivDateTimeToUnix(DateTime2UnivDateTime(dateEnd+1))]))+')';
   end;
   end;
 
 
   Result := 'SELECT '+sqltop+' * '+
   Result := 'SELECT '+sqltop+' * '+
@@ -878,7 +878,7 @@ begin
   End;
   End;
 end;
 end;
 
 
-function TDBStorage.ValueToSql(const Value: Variant): String;
+class function TDBStorage.ValueToSql(const Value: Variant): String;
 Var decs,ths : Char;
 Var decs,ths : Char;
   dates,times : char;
   dates,times : char;
 begin
 begin
@@ -911,7 +911,7 @@ begin
            Else Result := 'FALSE'
            Else Result := 'FALSE'
                       End;
                       End;
          varString,varOleStr,varUString  : Begin
          varString,varOleStr,varUString  : Begin
-             Result := VarToStr(Value);
+             Result := ''''+VarToStr(Value)+'''';
            End;
            End;
       Else // Case
       Else // Case
         Raise Exception.Create('Invalid variant Type: '+InttoHex(VarType(Value),8));
         Raise Exception.Create('Invalid variant Type: '+InttoHex(VarType(Value),8));
@@ -941,7 +941,7 @@ Var P : POperationResume;
   i : Integer;
   i : Integer;
   l : TList;
   l : TList;
 begin
 begin
-  l := FList.LockList('TOperationsResumeList.Clear');
+  l := FList.LockList;
   try
   try
     for i := 0 to l.Count - 1 do begin
     for i := 0 to l.Count - 1 do begin
       P := l[i];
       P := l[i];
@@ -956,7 +956,7 @@ end;
 function TOperationsResumeList.Count: Integer;
 function TOperationsResumeList.Count: Integer;
 Var l : TList;
 Var l : TList;
 begin
 begin
-  l := FList.LockList('TOperationsResumeList.Count');
+  l := FList.LockList;
   Try
   Try
     Result := l.Count;
     Result := l.Count;
   Finally
   Finally
@@ -973,7 +973,7 @@ procedure TOperationsResumeList.Delete(index: Integer);
 Var P : POperationResume;
 Var P : POperationResume;
   l : TList;
   l : TList;
 begin
 begin
-  l := FList.LockList('TOperationsResumeList.Delete');
+  l := FList.LockList;
   Try
   Try
     P := l[index];
     P := l[index];
     l.Delete(index);
     l.Delete(index);
@@ -993,7 +993,7 @@ end;
 function TOperationsResumeList.GetOperationResume(index: Integer): TOperationResume;
 function TOperationsResumeList.GetOperationResume(index: Integer): TOperationResume;
 Var l : TList;
 Var l : TList;
 begin
 begin
-  l := FList.LockList('TOperationsResumeList.GetOperationResume');
+  l := FList.LockList;
   try
   try
     if index<l.Count then Result := POperationResume(l[index])^
     if index<l.Count then Result := POperationResume(l[index])^
     else Result := CT_TOperationResume_NUL;
     else Result := CT_TOperationResume_NUL;

+ 2 - 2
Units/PascalCoin/UMiner.pas

@@ -129,7 +129,7 @@ begin
     Try
     Try
       if Terminated then exit;
       if Terminated then exit;
       winner := false;
       winner := false;
-      TPCThread.ProtectEnterCriticalSection(Self,'Mining process',FLock);
+      TPCThread.ProtectEnterCriticalSection(Self,FLock);
       try
       try
         FOperations.UpdateTimestamp;
         FOperations.UpdateTimestamp;
         FOperations.AccountKey := FAccountKey;
         FOperations.AccountKey := FAccountKey;
@@ -187,7 +187,7 @@ end;
 
 
 function TMinerThread.MinerLockOperations: TPCOperationsComp;
 function TMinerThread.MinerLockOperations: TPCOperationsComp;
 begin
 begin
-  TPCThread.ProtectEnterCriticalSection(Self,'MinerLockOperations',FLock);
+  TPCThread.ProtectEnterCriticalSection(Self,FLock);
   Result := FOperations;
   Result := FOperations;
 end;
 end;
 
 

File diff suppressed because it is too large
+ 312 - 149
Units/PascalCoin/UNetProtocol.pas


+ 14 - 10
Units/PascalCoin/UNode.pas

@@ -38,6 +38,7 @@ Type
     FNetServer : TNetServer;
     FNetServer : TNetServer;
     FMinerThreads : TPCThreadList;
     FMinerThreads : TPCThreadList;
     FBCBankNotify : TPCBankNotify;
     FBCBankNotify : TPCBankNotify;
+    FPeerCache : AnsiString;
     Procedure OnBankNewBlock(Sender : TObject);
     Procedure OnBankNewBlock(Sender : TObject);
     Procedure StartLocking(MaxWaitMilliseconds : Cardinal);
     Procedure StartLocking(MaxWaitMilliseconds : Cardinal);
     Procedure EndLocking;
     Procedure EndLocking;
@@ -68,6 +69,7 @@ Type
     Procedure AutoDiscoverNodes(Const ips : AnsiString);
     Procedure AutoDiscoverNodes(Const ips : AnsiString);
     Function IsBlockChainValid(var WhyNot : AnsiString) : Boolean;
     Function IsBlockChainValid(var WhyNot : AnsiString) : Boolean;
     Function IsReady(Var CurrentProcess : AnsiString) : Boolean;
     Function IsReady(Var CurrentProcess : AnsiString) : Boolean;
+    Property PeerCache : AnsiString read FPeerCache write FPeerCache;
   End;
   End;
 
 
   TNodeNotifyEvents = Class;
   TNodeNotifyEvents = Class;
@@ -181,7 +183,7 @@ begin
     if Result then begin
     if Result then begin
       FOperations.SanitizeOperations;
       FOperations.SanitizeOperations;
       // Notify to all clients and other miners
       // Notify to all clients and other miners
-      mtl := FMinerThreads.LockList('TNode.AddNewBlockChain - Notify clients');
+      mtl := FMinerThreads.LockList;
       try
       try
         for i := 0 to mtl.Count - 1 do begin
         for i := 0 to mtl.Count - 1 do begin
           if (mtl[i]<>SenderMiner) then begin
           if (mtl[i]<>SenderMiner) then begin
@@ -223,7 +225,7 @@ begin
           SenderMiner.MinerUnLockOperations(true);
           SenderMiner.MinerUnLockOperations(true);
         end;
         end;
         // Reset others:
         // Reset others:
-        mtl := FMinerThreads.LockList('TNode.AddNewBlockChain - Reset others');
+        mtl := FMinerThreads.LockList;
         try
         try
           for i := 0 to mtl.Count - 1 do begin
           for i := 0 to mtl.Count - 1 do begin
             if (TMinerThread(mtl[i])<>SenderMiner) then begin
             if (TMinerThread(mtl[i])<>SenderMiner) then begin
@@ -301,7 +303,7 @@ begin
       end;
       end;
       if Result=0 then exit;
       if Result=0 then exit;
       // Send to miners
       // Send to miners
-      mtl := FMinerThreads.LockList('TNode.AddOperations');
+      mtl := FMinerThreads.LockList;
       Try
       Try
         for i := 0 to mtl.Count - 1 do begin
         for i := 0 to mtl.Count - 1 do begin
           operationscomp := TMinerThread(mtl[i]).MinerLockOperations;
           operationscomp := TMinerThread(mtl[i]).MinerLockOperations;
@@ -376,7 +378,7 @@ Var i,j : Integer;
   ips_string : AnsiString;
   ips_string : AnsiString;
   nsa : TNodeServerAddress;
   nsa : TNodeServerAddress;
 begin
 begin
-  ips_string := ips;
+  ips_string := ips+';'+PeerCache;
   repeat
   repeat
     If GetIp(ips_string,nsa) then begin
     If GetIp(ips_string,nsa) then begin
       TNetData.NetData.AddServer(nsa);
       TNetData.NetData.AddServer(nsa);
@@ -411,7 +413,7 @@ procedure TNode.DeleteMiner(index: Integer);
 Var m : TMinerThread;
 Var m : TMinerThread;
   mtl : TList;
   mtl : TList;
 begin
 begin
-  mtl := FMinerThreads.LockList('TNode.DeleteMiner');
+  mtl := FMinerThreads.LockList;
   Try
   Try
     m := TMinerThread(mtl[index]);
     m := TMinerThread(mtl[index]);
     m.Suspended := false;
     m.Suspended := false;
@@ -517,7 +519,7 @@ end;
 function TNode.MinersCount : Integer;
 function TNode.MinersCount : Integer;
 Var mtl : TList;
 Var mtl : TList;
 begin
 begin
-  mtl := FMinerThreads.LockList('TNode.MinersCount');
+  mtl := FMinerThreads.LockList;
   Try
   Try
     Result := mtl.Count;
     Result := mtl.Count;
   Finally
   Finally
@@ -720,8 +722,9 @@ end;
 
 
 procedure TThreadNodeNotifyNewBlock.BCExecute;
 procedure TThreadNodeNotifyNewBlock.BCExecute;
 begin
 begin
-  If Not TNetData.NetData.ConnectionExists(FNetConnection) then begin
-    TLog.NewLog(ltdebug,Classname,'Connection not exists');
+  If Not TNetData.NetData.ConnectionExistsAndActive(FNetConnection) then begin
+    TLog.NewLog(ltdebug,Classname,'Connection not active');
+    exit;
   end;
   end;
   TLog.NewLog(ltdebug,ClassName,'Sending new block found to '+FNetConnection.Client.RemoteHost+':'+FNetConnection.Client.RemotePort);
   TLog.NewLog(ltdebug,ClassName,'Sending new block found to '+FNetConnection.Client.RemoteHost+':'+FNetConnection.Client.RemotePort);
   FNetConnection.Send_NewBlockFound;
   FNetConnection.Send_NewBlockFound;
@@ -742,8 +745,9 @@ end;
 
 
 procedure TThreadNodeNotifyOperations.BCExecute;
 procedure TThreadNodeNotifyOperations.BCExecute;
 begin
 begin
-  If Not TNetData.NetData.ConnectionExists(FNetConnection) then begin
-    TLog.NewLog(ltdebug,Classname,'Connection not exists');
+  If Not TNetData.NetData.ConnectionExistsAndActive(FNetConnection) then begin
+    TLog.NewLog(ltdebug,Classname,'Connection not active');
+    exit;
   end;
   end;
   if FOperationsHashTree.OperationsCount<=0 then exit;
   if FOperationsHashTree.OperationsCount<=0 then exit;
   TLog.NewLog(ltdebug,ClassName,'Sending '+inttostr(FOperationsHashTree.OperationsCount)+' Operations to '+FNetConnection.Client.RemoteHost+':'+FNetConnection.Client.RemotePort);
   TLog.NewLog(ltdebug,ClassName,'Sending '+inttostr(FOperationsHashTree.OperationsCount)+' Operations to '+FNetConnection.Client.RemoteHost+':'+FNetConnection.Client.RemotePort);

+ 24 - 21
Units/PascalCoin/UThread.pas

@@ -23,6 +23,7 @@ Type
   TPCThreadClass = Class of TPCThread;
   TPCThreadClass = Class of TPCThread;
   TPCThread = Class(TThread)
   TPCThread = Class(TThread)
   private
   private
+    FDebugStep: String;
   protected
   protected
     procedure DoTerminate; override;
     procedure DoTerminate; override;
     procedure Execute; override;
     procedure Execute; override;
@@ -32,7 +33,8 @@ Type
     Class function ThreadCount : Integer;
     Class function ThreadCount : Integer;
     Class function GetThread(index : Integer) : TPCThread;
     Class function GetThread(index : Integer) : TPCThread;
     Class function TerminateAllThreads : Integer;
     Class function TerminateAllThreads : Integer;
-    Class Procedure ProtectEnterCriticalSection(Const Sender : TObject; Const Subject : String; var Lock : TRTLCriticalSection);
+    Class Procedure ProtectEnterCriticalSection(Const Sender : TObject; var Lock : TRTLCriticalSection);
+    Property DebugStep : String read FDebugStep write FDebugStep;
   End;
   End;
 
 
   TPCThreadList = class
   TPCThreadList = class
@@ -45,7 +47,7 @@ Type
     procedure Add(Item: Pointer; Const Subject : String);
     procedure Add(Item: Pointer; Const Subject : String);
     procedure Clear;
     procedure Clear;
     procedure Remove(Item: Pointer); inline;
     procedure Remove(Item: Pointer); inline;
-    function LockList(Const Subject : String): TList;
+    function LockList: TList;
     procedure UnlockList; inline;
     procedure UnlockList; inline;
   end;
   end;
 
 
@@ -67,24 +69,25 @@ end;
 procedure TPCThread.Execute;
 procedure TPCThread.Execute;
 Var l : TList;
 Var l : TList;
 begin
 begin
+  FDebugStep := '';
   _threads.Add(Self,'TPCThread.Execute');
   _threads.Add(Self,'TPCThread.Execute');
   try
   try
-    TLog.NewLog(ltdebug,Classname,'Starting Thread');
+//    TLog.NewLog(ltdebug,Classname,'Starting Thread');
     Try
     Try
       Try
       Try
         BCExecute;
         BCExecute;
       Except
       Except
         On E:Exception do begin
         On E:Exception do begin
-          TLog.NewLog(lterror,Classname,'Exception inside a Thread ('+E.ClassName+'): '+E.Message);
+          TLog.NewLog(lterror,Classname,'Exception inside a Thread at step: '+FDebugStep+' ('+E.ClassName+'): '+E.Message);
           Raise;
           Raise;
         end;
         end;
       End;
       End;
     Finally
     Finally
-      TLog.NewLog(ltdebug,Classname,'Finalizing Thread');
+//      TLog.NewLog(ltdebug,Classname,'Finalizing Thread');
     End;
     End;
   finally
   finally
     if (Assigned(_threads)) then begin
     if (Assigned(_threads)) then begin
-      l := _threads.LockList('TPCThread.Execute');
+      l := _threads.LockList;
       Try
       Try
         l.Remove(Self);
         l.Remove(Self);
       Finally
       Finally
@@ -98,7 +101,7 @@ class function TPCThread.GetThread(index: Integer): TPCThread;
 Var l : TList;
 Var l : TList;
 begin
 begin
   Result := Nil;
   Result := Nil;
-  l := _threads.LockList('TPCThread.GetThread');
+  l := _threads.LockList;
   try
   try
     if (index<0) or (index>=l.Count) then exit;
     if (index<0) or (index>=l.Count) then exit;
     Result := TPCThread(l[index]);
     Result := TPCThread(l[index]);
@@ -107,14 +110,14 @@ begin
   end;
   end;
 end;
 end;
 
 
-class procedure TPCThread.ProtectEnterCriticalSection(Const Sender : TObject; Const Subject : String; var Lock: TRTLCriticalSection);
+class procedure TPCThread.ProtectEnterCriticalSection(Const Sender : TObject; var Lock: TRTLCriticalSection);
 begin
 begin
   if Not TryEnterCriticalSection(Lock) then begin
   if Not TryEnterCriticalSection(Lock) then begin
-    TLog.NewLog(ltdebug,Sender.Classname,Format('Locked critical section (WAIT):'+Subject+' LockCount:%d RecursionCount:%d Semaphore:%d LockOwnerThread:%s',[
-      Lock.LockCount,Lock.RecursionCount,Lock.LockSemaphore,IntToHex(Lock.OwningThread,8) ]));
+//    TLog.NewLog(ltdebug,Sender.Classname,Format('Locked critical section (WAIT): LockCount:%d RecursionCount:%d Semaphore:%d LockOwnerThread:%s',[
+//      Lock.LockCount,Lock.RecursionCount,Lock.LockSemaphore,IntToHex(Lock.OwningThread,8) ]));
     EnterCriticalSection(Lock);
     EnterCriticalSection(Lock);
-    TLog.NewLog(ltdebug,Sender.Classname,Format('UnLocked critical section (ENTER):'+Subject+' LockCount:%d RecursionCount:%d Semaphore:%d LockOwnerThread:%s',[
-      Lock.LockCount,Lock.RecursionCount,Lock.LockSemaphore,IntToHex(Lock.OwningThread,8) ]));
+//    TLog.NewLog(ltdebug,Sender.Classname,Format('UnLocked critical section (ENTER): LockCount:%d RecursionCount:%d Semaphore:%d LockOwnerThread:%s',[
+//      Lock.LockCount,Lock.RecursionCount,Lock.LockSemaphore,IntToHex(Lock.OwningThread,8) ]));
   end;
   end;
 end;
 end;
 
 
@@ -124,7 +127,7 @@ Var l : TList;
 begin
 begin
   Result := -1;
   Result := -1;
   if Not Assigned(_threads) then exit;
   if Not Assigned(_threads) then exit;
-  l := _threads.LockList('TPCThread.TerminateAllThreads');
+  l := _threads.LockList;
   try
   try
     for i :=l.Count - 1 downto 0 do begin
     for i :=l.Count - 1 downto 0 do begin
       TPCThread(l[i]).Terminate;
       TPCThread(l[i]).Terminate;
@@ -142,7 +145,7 @@ Var l : TList;
 begin
 begin
   Result := -1;
   Result := -1;
   if Not Assigned(_threads) then exit;
   if Not Assigned(_threads) then exit;
-  l := _threads.LockList('TPCThread.ThreadClassFound');
+  l := _threads.LockList;
   try
   try
     for Result := 0 to l.Count - 1 do begin
     for Result := 0 to l.Count - 1 do begin
       if (TPCThread(l[Result]) is tclass) And ((l[Result])<>Exclude) then exit;
       if (TPCThread(l[Result]) is tclass) And ((l[Result])<>Exclude) then exit;
@@ -156,7 +159,7 @@ end;
 class function TPCThread.ThreadCount: Integer;
 class function TPCThread.ThreadCount: Integer;
 Var l : TList;
 Var l : TList;
 begin
 begin
-  l := _threads.LockList('TPCThread.ThreadCount');
+  l := _threads.LockList;
   try
   try
     Result := l.Count;
     Result := l.Count;
   finally
   finally
@@ -168,7 +171,7 @@ end;
 
 
 procedure TPCThreadList.Add(Item: Pointer; Const Subject : String);
 procedure TPCThreadList.Add(Item: Pointer; Const Subject : String);
 begin
 begin
-  LockList('TPCThreadList.Add - '+Subject);
+  LockList;
   Try
   Try
     FList.Add(Item);
     FList.Add(Item);
   Finally
   Finally
@@ -178,7 +181,7 @@ end;
 
 
 procedure TPCThreadList.Clear;
 procedure TPCThreadList.Clear;
 begin
 begin
-  LockList('TPCThreadList.Clear');
+  LockList;
   Try
   Try
     FList.Clear;
     FList.Clear;
   Finally
   Finally
@@ -194,7 +197,7 @@ end;
 
 
 destructor TPCThreadList.Destroy;
 destructor TPCThreadList.Destroy;
 begin
 begin
-  LockList('TPCThreadList.Destroy');
+  LockList;
   try
   try
     FList.Free;
     FList.Free;
     inherited Destroy;
     inherited Destroy;
@@ -204,15 +207,15 @@ begin
   end;
   end;
 end;
 end;
 
 
-function TPCThreadList.LockList(Const Subject : String): TList;
+function TPCThreadList.LockList: TList;
 begin
 begin
-  TPCThread.ProtectEnterCriticalSection(Self,Subject,FLock);
+  TPCThread.ProtectEnterCriticalSection(Self,FLock);
   Result := FList;
   Result := FList;
 end;
 end;
 
 
 procedure TPCThreadList.Remove(Item: Pointer);
 procedure TPCThreadList.Remove(Item: Pointer);
 begin
 begin
-  LockList('TPCThreadList.Remove');
+  LockList;
   try
   try
     FList.Remove(Item);
     FList.Remove(Item);
   finally
   finally

+ 2 - 0
Units/Utils/UAppParams.pas

@@ -297,6 +297,8 @@ end;
 
 
 procedure TAppParam.SetAsString(StringValue: AnsiString);
 procedure TAppParam.SetAsString(StringValue: AnsiString);
 begin
 begin
+  if (FParamType=ptString) And (GetAsString('')=StringValue) then exit;
+
   FParamType := ptString;
   FParamType := ptString;
   FValue := StringValue;
   FValue := StringValue;
   If Assigned(FAppParams) then FAppParams.Save;
   If Assigned(FAppParams) then FAppParams.Save;

+ 117 - 34
Units/Utils/UGridUtils.pas

@@ -31,7 +31,6 @@ Type
   TOrderedCardinalList = Class
   TOrderedCardinalList = Class
   private
   private
     FOrderedList : TList;
     FOrderedList : TList;
-    Function Find(const Value: Cardinal; var Index: Integer): Boolean;
   public
   public
     Constructor Create;
     Constructor Create;
     Destructor Destroy; override;
     Destructor Destroy; override;
@@ -40,6 +39,7 @@ Type
     Procedure Clear;
     Procedure Clear;
     Function Get(index : Integer) : Cardinal;
     Function Get(index : Integer) : Cardinal;
     Function Count : Integer;
     Function Count : Integer;
+    Function Find(const Value: Cardinal; var Index: Integer): Boolean;
   End;
   End;
 
 
   TAccountsGrid = Class(TComponent)
   TAccountsGrid = Class(TComponent)
@@ -71,6 +71,7 @@ Type
     Procedure LoadFromStream(Stream : TStream);
     Procedure LoadFromStream(Stream : TStream);
     Property ShowAllAccounts : Boolean read FShowAllAccounts write SetShowAllAccounts;
     Property ShowAllAccounts : Boolean read FShowAllAccounts write SetShowAllAccounts;
     Property AccountsBalance : Int64 read FAccountsBalance;
     Property AccountsBalance : Int64 read FAccountsBalance;
+    Function MoveRowToAccount(nAccount : Cardinal) : Boolean;
   End;
   End;
 
 
   TOperationsGrid = Class(TComponent)
   TOperationsGrid = Class(TComponent)
@@ -312,6 +313,44 @@ begin
   Result := FAccountsList;
   Result := FAccountsList;
 end;
 end;
 
 
+function TAccountsGrid.MoveRowToAccount(nAccount: Cardinal): Boolean;
+Var oal : TOrderedCardinalList;
+  idx : Integer;
+begin
+  Result := false;
+  if Not Assigned(FDrawGrid) then exit;
+  if Not Assigned(Node) then exit;
+  if FDrawGrid.RowCount<=1 then exit;
+  if FShowAllAccounts then begin
+    If (FDrawGrid.RowCount>nAccount+1) And (nAccount>=0) And (nAccount<Node.Bank.AccountsCount) then begin
+      FDrawGrid.Row := nAccount+1;
+      Result := true;
+    end else begin
+      FDrawGrid.Row := FDrawGrid.RowCount-1;
+    end;
+  end else begin
+    oal := LockAccountsList;
+    try
+      If oal.Find(nAccount,idx) then begin
+        If FDrawGrid.RowCount>idx+1 then begin
+          FDrawGrid.Row := idx+1;
+          Result := true;
+        end else begin
+          FDrawGrid.Row := FDrawGrid.RowCount-1;
+        end;
+      end else begin
+        If FDrawGrid.RowCount>idx+1 then begin
+          FDrawGrid.Row := idx+1;
+        end else begin
+          FDrawGrid.Row := FDrawGrid.RowCount-1;
+        end;
+      end;
+    finally
+      UnlockAccountsList;
+    end;
+  end;
+end;
+
 procedure TAccountsGrid.Notification(AComponent: TComponent;
 procedure TAccountsGrid.Notification(AComponent: TComponent;
   Operation: TOperation);
   Operation: TOperation);
 begin
 begin
@@ -729,7 +768,7 @@ end;
 procedure TOperationsGrid.SetNode(const Value: TNode);
 procedure TOperationsGrid.SetNode(const Value: TNode);
 begin
 begin
   FNodeNotifyEvents.Node := Value;
   FNodeNotifyEvents.Node := Value;
-  InitGrid;
+  UpdateAccountOperations; // New Build 1.0.3
 end;
 end;
 
 
 procedure TOperationsGrid.SetPendingOperations(const Value: Boolean);
 procedure TOperationsGrid.SetPendingOperations(const Value: Boolean);
@@ -842,10 +881,12 @@ begin
   fld.FieldName := CT_TblFld_Operations_block;
   fld.FieldName := CT_TblFld_Operations_block;
   fld.DataSet := FQrySQL;
   fld.DataSet := FQrySQL;
   fld.Visible := false;
   fld.Visible := false;
-  fld := TIntegerField.Create(FQrySQL);
-  fld.FieldName := CT_TblFld_Operations_timestamp;
+  //
+  fld := TStringField.Create(FQrySQL);
+  fld.FieldName := CT_TblFld_Operations_s_timestamp;
   fld.DataSet := FQrySQL;
   fld.DataSet := FQrySQL;
   fld.Visible := false;
   fld.Visible := false;
+  //
   fld := TIntegerField.Create(FQrySQL);
   fld := TIntegerField.Create(FQrySQL);
   fld.FieldName := CT_TblFld_Operations_optype;
   fld.FieldName := CT_TblFld_Operations_optype;
   fld.DataSet := FQrySQL;
   fld.DataSet := FQrySQL;
@@ -885,15 +926,34 @@ begin
   fld.FieldKind := fkCalculated;
   fld.FieldKind := fkCalculated;
   fld.DataSet := FQrySQL;
   fld.DataSet := FQrySQL;
   TStringField(fld).Size := 600;
   TStringField(fld).Size := 600;
-  fld := TIntegerField.Create(FQrySQL);
-  fld.FieldName := CT_TblFld_Operations_amount;
+  //
+  fld := TStringField.Create(FQrySQL);
+  fld.FieldName := CT_TblFld_Operations_s_amount;
   fld.DataSet := FQrySQL;
   fld.DataSet := FQrySQL;
-  fld := TIntegerField.Create(FQrySQL);
-  fld.FieldName := CT_TblFld_Operations_fee;
+  fld := TLargeintField.Create(FQrySQL);
+  fld.FieldName := 'amount';
+  fld.Calculated := true;
+  fld.FieldKind := fkCalculated;
   fld.DataSet := FQrySQL;
   fld.DataSet := FQrySQL;
-  fld := TIntegerField.Create(FQrySQL);
-  fld.FieldName := CT_TblFld_Operations_balance;
+
+  fld := TStringField.Create(FQrySQL);
+  fld.FieldName := CT_TblFld_Operations_s_fee;
+  fld.DataSet := FQrySQL;
+  fld := TLargeintField.Create(FQrySQL);
+  fld.FieldName := 'fee';
+  fld.Calculated := true;
+  fld.FieldKind := fkCalculated;
   fld.DataSet := FQrySQL;
   fld.DataSet := FQrySQL;
+
+  fld := TStringField.Create(FQrySQL);
+  fld.FieldName := CT_TblFld_Operations_s_balance;
+  fld.DataSet := FQrySQL;
+  fld := TLargeintField.Create(FQrySQL);
+  fld.FieldName := 'balance';
+  fld.Calculated := true;
+  fld.FieldKind := fkCalculated;
+  fld.DataSet := FQrySQL;
+
   fld := TStringField.Create(FQrySQL);
   fld := TStringField.Create(FQrySQL);
   fld.FieldName := CT_TblFld_Operations_rawpayload;
   fld.FieldName := CT_TblFld_Operations_rawpayload;
   fld.DataSet := FQrySQL;
   fld.DataSet := FQrySQL;
@@ -955,9 +1015,9 @@ begin
     else c.Brush.Color := clGradientInactiveCaption
     else c.Brush.Color := clGradientInactiveCaption
   else c.Brush.Color := clWindow;
   else c.Brush.Color := clWindow;
   c.FillRect(Rect);
   c.FillRect(Rect);
-  if SameText(Column.FieldName,CT_TblFld_Operations_amount) Or
-     SameText(Column.FieldName,CT_TblFld_Operations_fee) Or
-     SameText(Column.FieldName,CT_TblFld_Operations_balance)
+  if SameText(Column.FieldName,'amount') Or
+     SameText(Column.FieldName,'fee') Or
+     SameText(Column.FieldName,'balance')
       then begin
       then begin
     c.FillRect(Rect);
     c.FillRect(Rect);
     if Column.Field.AsLargeInt>0 then c.Font.Color := ClGreen
     if Column.Field.AsLargeInt>0 then c.Font.Color := ClGreen
@@ -990,7 +1050,7 @@ Var fld : TField;
   s : AnsiString;
   s : AnsiString;
 begin
 begin
   fld := DataSet.FieldByName('datetime');
   fld := DataSet.FieldByName('datetime');
-  fld.AsDateTime :=  UnivDateTime2LocalDateTime(UnixToUnivDateTime(DataSet.FieldByName(CT_TblFld_Operations_timestamp).AsInteger));
+  fld.AsDateTime :=  UnivDateTime2LocalDateTime(UnixToUnivDateTime( StrToIntDef( DataSet.FieldByName(CT_TblFld_Operations_s_timestamp).AsString, 0)));
   fld := DataSet.FieldByName('op_account');
   fld := DataSet.FieldByName('op_account');
   fld.AsString := TAccountComp.AccountNumberToAccountTxtNumber(DataSet.FieldByName(CT_TblFld_Operations_account).AsInteger);
   fld.AsString := TAccountComp.AccountNumberToAccountTxtNumber(DataSet.FieldByName(CT_TblFld_Operations_account).AsInteger);
   fld := DataSet.FieldByName('payload_txt');
   fld := DataSet.FieldByName('payload_txt');
@@ -1000,6 +1060,14 @@ begin
   end else begin
   end else begin
     fld.AsString := TCrypto.ToHexaString(raw);
     fld.AsString := TCrypto.ToHexaString(raw);
   end;
   end;
+  //
+  fld := DataSet.FieldByName('amount');
+  TLargeintField(fld).Value := StrToInt64Def(Dataset.FieldByName(CT_TblFld_Operations_s_amount).AsString,0);
+  fld := DataSet.FieldByName('balance');
+  TLargeintField(fld).Value := StrToInt64Def(Dataset.FieldByName(CT_TblFld_Operations_s_balance).AsString,0);
+  fld := DataSet.FieldByName('fee');
+  TLargeintField(fld).Value := StrToInt64Def(Dataset.FieldByName(CT_TblFld_Operations_s_fee).AsString,0);
+
   fld := DataSet.FieldByName('operation');
   fld := DataSet.FieldByName('operation');
           case dataset.FieldByName(CT_TblFld_Operations_optype).AsInteger of
           case dataset.FieldByName(CT_TblFld_Operations_optype).AsInteger of
             0 : fld.AsString := 'Blockchain reward';
             0 : fld.AsString := 'Blockchain reward';
@@ -1029,7 +1097,7 @@ begin
     exit;
     exit;
   end;
   end;
   FNeedRefreshSQL := false;
   FNeedRefreshSQL := false;
-  sql := TDBStorage.GetOperationsFromAccountSQL(AccountNumber,BlockStart,BlockEnd,DateStart,DateEnd, 0,0);
+  sql := TDBStorage.GetOperationsFromAccountSQL(AccountNumber,BlockStart,BlockEnd,DateStart,DateEnd, 0,50000);
   If FQrySQL.Connection=Nil then exit;
   If FQrySQL.Connection=Nil then exit;
   if Node=Nil then exit;
   if Node=Nil then exit;
   if FDBGrid=Nil then exit;
   if FDBGrid=Nil then exit;
@@ -1135,9 +1203,9 @@ begin
     AddColumn('datetime','Date/Time',120);
     AddColumn('datetime','Date/Time',120);
     AddColumn('op_account','Account',70);
     AddColumn('op_account','Account',70);
     AddColumn('operation','Operation',150);
     AddColumn('operation','Operation',150);
-    AddColumn(CT_TblFld_Operations_amount,'Amount',80);
-    AddColumn(CT_TblFld_Operations_fee,'Fee',60);
-    AddColumn(CT_TblFld_Operations_balance,'Balance',80);
+    AddColumn('amount','Amount',80);
+    AddColumn('fee','Fee',60);
+    AddColumn('balance','Balance',80);
     AddColumn('payload_txt','Payload',280);
     AddColumn('payload_txt','Payload',280);
     RefreshData;
     RefreshData;
   end;
   end;
@@ -1158,7 +1226,8 @@ begin
   FRM := TFRMPayloadDecoder.Create(FDBGrid.Owner);
   FRM := TFRMPayloadDecoder.Create(FDBGrid.Owner);
   try
   try
     TDBStorage.DBStringFieldToRaw(FQrySQL.FieldByName(CT_TblFld_Operations_rawpayload),raw);
     TDBStorage.DBStringFieldToRaw(FQrySQL.FieldByName(CT_TblFld_Operations_rawpayload),raw);
-    FRM.Init(FQrySQL.FieldByName(CT_TblFld_Operations_block).AsInteger,FQrySQL.FieldByName(CT_TblFld_Operations_timestamp).AsInteger,
+    FRM.Init(FQrySQL.FieldByName(CT_TblFld_Operations_block).AsInteger,
+      StrToIntDef( FQrySQL.FieldByName(CT_TblFld_Operations_s_timestamp).AsString,0),
       FQrySQL.FieldByName('operation').AsString,
       FQrySQL.FieldByName('operation').AsString,
       raw,WalletKeys,AppParams);
       raw,WalletKeys,AppParams);
     FRM.ShowModal;
     FRM.ShowModal;
@@ -1191,20 +1260,20 @@ begin
   fld.FieldName := CT_TblFld_BlockChain_block;
   fld.FieldName := CT_TblFld_BlockChain_block;
   fld.DataSet := FQrySQL;
   fld.DataSet := FQrySQL;
   fld.Visible := true;
   fld.Visible := true;
-  fld := TIntegerField.Create(FQrySQL);
-  fld.FieldName := CT_TblFld_BlockChain_timestamp;
+  fld := TStringField.Create(FQrySQL);
+  fld.FieldName := CT_TblFld_BlockChain_s_timestamp;
   fld.DataSet := FQrySQL;
   fld.DataSet := FQrySQL;
   fld.Visible := false;
   fld.Visible := false;
-  fld := TIntegerField.Create(FQrySQL);
-  fld.FieldName := CT_TblFld_BlockChain_reward;
+  fld := TStringField.Create(FQrySQL);
+  fld.FieldName := CT_TblFld_BlockChain_s_reward;
   fld.DataSet := FQrySQL;
   fld.DataSet := FQrySQL;
   fld.Visible := true;
   fld.Visible := true;
-  fld := TIntegerField.Create(FQrySQL);
-  fld.FieldName := CT_TblFld_BlockChain_fee;
+  fld := TStringField.Create(FQrySQL);
+  fld.FieldName := CT_TblFld_BlockChain_s_fee;
   fld.DataSet := FQrySQL;
   fld.DataSet := FQrySQL;
   fld.Visible := true;
   fld.Visible := true;
-  fld := TIntegerField.Create(FQrySQL);
-  fld.FieldName := CT_TblFld_BlockChain_compact_target;
+  fld := TStringField.Create(FQrySQL);
+  fld.FieldName := CT_TblFld_BlockChain_s_compact_target;
   fld.DataSet := FQrySQL;
   fld.DataSet := FQrySQL;
   fld.Visible := true;
   fld.Visible := true;
   fld := TIntegerField.Create(FQrySQL);
   fld := TIntegerField.Create(FQrySQL);
@@ -1233,6 +1302,18 @@ begin
   fld.DataSet := FQrySQL;
   fld.DataSet := FQrySQL;
   TStringField(fld).Size := 8;
   TStringField(fld).Size := 8;
 
 
+  fld := TLargeintField.Create(FQrySQL);
+  fld.FieldName := 'reward';
+  fld.Calculated := true;
+  fld.FieldKind := fkCalculated;
+  fld.DataSet := FQrySQL;
+
+  fld := TLargeintField.Create(FQrySQL);
+  fld.FieldName := 'fee';
+  fld.Calculated := true;
+  fld.FieldKind := fkCalculated;
+  fld.DataSet := FQrySQL;
+
   fld := TStringField.Create(FQrySQL);
   fld := TStringField.Create(FQrySQL);
   fld.FieldName := CT_TblFld_BlockChain_rawpayload;
   fld.FieldName := CT_TblFld_BlockChain_rawpayload;
   fld.DataSet := FQrySQL;
   fld.DataSet := FQrySQL;
@@ -1299,8 +1380,8 @@ begin
     else c.Brush.Color := clGradientInactiveCaption
     else c.Brush.Color := clGradientInactiveCaption
   else c.Brush.Color := clWindow;
   else c.Brush.Color := clWindow;
   c.FillRect(Rect);
   c.FillRect(Rect);
-  if SameText(Column.FieldName,CT_TblFld_BlockChain_reward) Or
-     SameText(Column.FieldName,CT_TblFld_BlockChain_fee)
+  if SameText(Column.FieldName,'reward') Or
+     SameText(Column.FieldName,'fee')
       then begin
       then begin
     c.FillRect(Rect);
     c.FillRect(Rect);
     if Column.Field.AsLargeInt>0 then c.Font.Color := ClGreen
     if Column.Field.AsLargeInt>0 then c.Font.Color := ClGreen
@@ -1333,9 +1414,11 @@ Var fld : TField;
   s : AnsiString;
   s : AnsiString;
 begin
 begin
   fld := DataSet.FieldByName('datetime');
   fld := DataSet.FieldByName('datetime');
-  fld.AsDateTime :=  UnivDateTime2LocalDateTime(UnixToUnivDateTime(DataSet.FieldByName(CT_TblFld_BlockChain_timestamp).AsInteger));
+  fld.AsDateTime :=  UnivDateTime2LocalDateTime(UnixToUnivDateTime(StrToIntDef( DataSet.FieldByName(CT_TblFld_BlockChain_s_timestamp).AsString,0)));
   fld := DataSet.FieldByName('target');
   fld := DataSet.FieldByName('target');
-  fld.AsString :=  IntToHex(DataSet.FieldByName(CT_TblFld_BlockChain_compact_target).AsInteger,8);
+  fld.AsString :=  IntToHex(StrToIntDef( DataSet.FieldByName(CT_TblFld_BlockChain_s_compact_target).AsString,0),8);
+  DataSet.FieldByName('reward').AsLargeInt := StrToIntDef(DataSet.FieldByName(CT_TblFld_BlockChain_s_reward).AsString,0);
+  DataSet.FieldByName('fee').AsLargeInt := StrToIntDef(DataSet.FieldByName(CT_TblFld_BlockChain_s_fee).AsString,0);
   fld := DataSet.FieldByName('payload_decoded');
   fld := DataSet.FieldByName('payload_decoded');
   TDBStorage.DBStringFieldToRaw(DataSet.FieldByName(CT_TblFld_BlockChain_rawpayload),raw);
   TDBStorage.DBStringFieldToRaw(DataSet.FieldByName(CT_TblFld_BlockChain_rawpayload),raw);
   If TDBStorage.DBPayloadToReadableText(raw,s) then begin
   If TDBStorage.DBPayloadToReadableText(raw,s) then begin
@@ -1353,7 +1436,7 @@ begin
     exit;
     exit;
   end;
   end;
   FNeedRefreshSQL := false;
   FNeedRefreshSQL := false;
-  sql := TDBStorage.GetBlockChainSQL(BlockStart,BlockEnd,DateStart,DateEnd, 0,100);
+  sql := TDBStorage.GetBlockChainSQL(BlockStart,BlockEnd,DateStart,DateEnd, 0,300);
   If FQrySQL.Connection=Nil then exit;
   If FQrySQL.Connection=Nil then exit;
   if Node=Nil then exit;
   if Node=Nil then exit;
   if FDBGrid=Nil then exit;
   if FDBGrid=Nil then exit;
@@ -1449,8 +1532,8 @@ begin
     AddColumn(CT_TblFld_BlockChain_block,'Block',50);
     AddColumn(CT_TblFld_BlockChain_block,'Block',50);
     AddColumn('datetime','Date/Time',120);
     AddColumn('datetime','Date/Time',120);
     AddColumn(CT_TblFld_BlockChain_operations_count,'Ops.',50);
     AddColumn(CT_TblFld_BlockChain_operations_count,'Ops.',50);
-    AddColumn(CT_TblFld_BlockChain_reward,'Reward',80);
-    AddColumn(CT_TblFld_BlockChain_fee,'Fee',60);
+    AddColumn('reward','Reward',80);
+    AddColumn('fee','Fee',60);
     AddColumn('target','Target',65);
     AddColumn('target','Target',65);
     AddColumn(CT_TblFld_BlockChain_safe_box_hash,'Safe Box Hash',350);
     AddColumn(CT_TblFld_BlockChain_safe_box_hash,'Safe Box Hash',350);
     AddColumn('payload_decoded','Miner Payload',150);
     AddColumn('payload_decoded','Miner Payload',150);

BIN
pascalcoin.mdb


BIN
pascalcoinB03.mdb


Some files were not shown because too many files changed in this diff