diff --git a/.gitignore b/.gitignore index e23da0e89..14dfea2d1 100644 --- a/.gitignore +++ b/.gitignore @@ -48,6 +48,7 @@ __history/ __recovery/ dunit.ini *.res +*.rsm /*.DS_Store /PIP/*.DS_Store /PIP/resources/*.DS_Store diff --git a/src/core/UConst.pas b/src/core/UConst.pas index e5efef33d..0e5a08821 100644 --- a/src/core/UConst.pas +++ b/src/core/UConst.pas @@ -29,7 +29,7 @@ interface type PtrInt = NativeInt; PtrUInt = NativeUInt; - TThreadID = NativeUInt; + TThreadID = NativeUInt; // Skybuck: already defined in system under Delphi, could lead to (proto)type mismatches, consider disabling this in Delphi for more safety ?!? ULog.pas is activated by this as well as UFrameLogs.pas {$ENDIF} Const diff --git a/src/gui-classic/Frames/UFrameAccountExplorer.dfm b/src/gui-classic/Frames/UFrameAccountExplorer.dfm new file mode 100644 index 000000000..080e958aa --- /dev/null +++ b/src/gui-classic/Frames/UFrameAccountExplorer.dfm @@ -0,0 +1,445 @@ +object FrameAccountExplorer: TFrameAccountExplorer + Left = 0 + Top = 0 + Width = 820 + Height = 582 + TabOrder = 0 + object Splitter1: TSplitter + Left = 400 + Top = 66 + Width = 5 + Height = 516 + ExplicitLeft = 315 + ExplicitTop = -132 + ExplicitHeight = 372 + end + object pnlMyAccountsTop: TPanel + Left = 0 + Top = 0 + Width = 820 + Height = 66 + Align = alTop + BevelOuter = bvNone + TabOrder = 0 + object Label18: TLabel + Left = 11 + Top = 35 + Width = 61 + Height = 13 + Caption = 'Find account' + Color = clBtnFace + ParentColor = False + end + object sbSearchAccount: TSpeedButton + Left = 176 + Top = 32 + Width = 23 + Height = 22 + Glyph.Data = { + 36030000424D3603000000000000360000002800000010000000100000000100 + 18000000000000030000120B0000120B00000000000000000000FF00FF4A667C + BE9596FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FF6B9CC31E89E84B7AA3C89693FF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF4BB4FE51B5FF + 2089E94B7AA2C69592FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FF51B7FE51B3FF1D87E64E7AA0CA9792FF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + 51B7FE4EB2FF1F89E64E7BA2B99497FF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF52B8FE4BB1FF2787D95F6A76FF + 00FFB0857FC09F94C09F96BC988EFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + FF00FFFF00FF55BDFFB5D6EDBF9D92BB9B8CE7DAC2FFFFE3FFFFE5FDFADAD8C3 + B3B58D85FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFCEA795FD + EEBEFFFFD8FFFFDAFFFFDBFFFFE6FFFFFBEADDDCAE837FFF00FFFF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFC1A091FBDCA8FEF7D0FFFFDBFFFFE3FFFFF8FFFF + FDFFFFFDC6A99CFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFC1A091FEE3ACF1 + C491FCF2CAFFFFDDFFFFE4FFFFF7FFFFF7FFFFE9EEE5CBB9948CFF00FFFF00FF + FF00FFFF00FFFF00FFC2A191FFE6AEEEB581F7DCAEFEFDD8FFFFDFFFFFE3FFFF + E4FFFFE0F3ECD2BB968EFF00FFFF00FFFF00FFFF00FFFF00FFBC978CFBE7B7F4 + C791F2C994F8E5B9FEFCD8FFFFDDFFFFDCFFFFE0E2D2BAB68E86FF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFD9C3A9FFFEE5F7DCB8F2C994F5D4A5FAE8BDFDF4 + C9FDFBD6B69089FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFB58D85E8 + DEDDFFFEF2F9D8A3F4C48CF9D49FFDEAB8D0B49FB89086FF00FFFF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFAD827FC9AA9EEFE0B7EFDFB2E7CEACB890 + 86B89086FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFBA968ABB988CB79188FF00FFFF00FFFF00FFFF00FF} + OnClick = sbSearchAccountClick + end + object cbMyPrivateKeys: TComboBox + Left = 260 + Top = 7 + Width = 411 + Height = 21 + Style = csDropDownList + TabOrder = 0 + OnChange = cbMyPrivateKeysChange + end + object cbExploreMyAccounts: TCheckBox + Left = 11 + Top = 10 + Width = 235 + Height = 19 + Caption = 'Explore accounts with one of my Wallet Keys' + TabOrder = 1 + OnClick = cbExploreMyAccountsClick + end + object ebFindAccountNumber: TEdit + Left = 87 + Top = 33 + Width = 83 + Height = 21 + TabOrder = 3 + OnChange = ebFindAccountNumberChange + OnExit = ebFindAccountNumberExit + end + object bbChangeKeyName: TBitBtn + Left = 685 + Top = 5 + Width = 126 + Height = 25 + Caption = 'Change Key name' + TabOrder = 2 + OnClick = bbChangeKeyNameClick + end + object cbFilterAccounts: TCheckBox + Left = 260 + Top = 35 + Width = 145 + Height = 19 + Caption = 'Filter accounts by balance' + TabOrder = 4 + OnClick = cbFilterAccountsClick + end + object ebFilterAccountByBalanceMin: TEdit + Left = 412 + Top = 33 + Width = 83 + Height = 21 + Hint = 'Min balance' + TabOrder = 5 + OnExit = ebFilterAccountByBalanceMinExit + OnKeyPress = ebFilterAccountByBalanceMinKeyPress + end + object ebFilterAccountByBalanceMax: TEdit + Left = 503 + Top = 33 + Width = 83 + Height = 21 + Hint = 'Max balance' + TabOrder = 6 + OnExit = ebFilterAccountByBalanceMaxExit + OnKeyPress = ebFilterAccountByBalanceMaxKeyPress + end + end + object pnlAccounts: TPanel + Left = 0 + Top = 66 + Width = 400 + Height = 516 + Align = alLeft + BevelOuter = bvNone + TabOrder = 1 + object dgAccounts: TDrawGrid + Left = 0 + Top = 0 + Width = 400 + Height = 482 + Align = alClient + TabOrder = 0 + OnClick = dgAccountsClick + end + object pnlAccountsInfo: TPanel + Left = 0 + Top = 482 + Width = 400 + Height = 34 + Align = alBottom + BevelOuter = bvNone + TabOrder = 1 + DesignSize = ( + 400 + 34) + object Label17: TLabel + Left = 5 + Top = 10 + Width = 48 + Height = 13 + Caption = 'Accounts:' + Color = clBtnFace + ParentColor = False + end + object Label19: TLabel + Left = 136 + Top = 10 + Width = 41 + Height = 13 + Caption = 'Balance:' + Color = clBtnFace + ParentColor = False + end + object lblAccountsCount: TLabel + Left = 60 + Top = 10 + Width = 18 + Height = 13 + Caption = '000' + Color = clBtnFace + ParentColor = False + end + object lblAccountsBalance: TLabel + Left = 200 + Top = 10 + Width = 18 + Height = 13 + Caption = '000' + Color = clBtnFace + ParentColor = False + end + object bbAccountsRefresh: TBitBtn + Left = 322 + Top = 6 + Width = 75 + Height = 25 + Anchors = [akTop, akRight] + Caption = 'Refresh' + Glyph.Data = { + 36030000424D3603000000000000360000002800000010000000100000000100 + 18000000000000030000120B0000120B00000000000000000000FF00FFFF00FF + C2A6A4C2A6A4C2A6A4C2A6A4C2A6A4C2A6A4C2A6A4C2A6A4C2A6A4C2A6A4C2A6 + A4C2A6A4FF00FFFF00FFFF00FFFF00FFC2A6A4FEFCFBFEFCFBFEFCFBFEFCFBFE + FCFBFEFCFBFEFCFBFEFCFBFEFCFBFEFCFBC2A6A4FF00FFFF00FFFF00FFFF00FF + C2A6A4FEFCFBFEFCFBFEFCFBFEFCFBD8EBD6018A02018A02D8EBD6FEFCFBFEFC + FBC2A6A4FF00FFFF00FFFF00FFFF00FFC2A6A4FEFBF7FEFBF7018A02D8EAD201 + 8A02D8EAD2D8EAD2018A02FEFBF7FEFBF7C2A6A4FF00FFFF00FFFF00FFFF00FF + C2A6A4FEF9F4FEF9F4018A02018A02D8E8D0FEF9F4FEF9F4D8E8D0FEF9F4FEF9 + F4C2A6A4FF00FFFF00FFFF00FFFF00FFC2A6A4FEF7F0FEF7F0018A02018A0201 + 8A02FEF7F0FEF7F0FEF7F0FEF7F0FEF7F0C2A6A4FF00FFFF00FFFF00FFFF00FF + C2A6A4FEF5ECFEF5ECFEF5ECFEF5ECFEF5EC018A02018A02018A02FEF5ECFEF5 + ECC2A6A4FF00FFFF00FFFF00FFFF00FFC2A6A4FEF3E9FEF3E9D8E3C7FEF3E9FE + F3E9D8E3C7018A02018A02FEF3E9FEF3E9C2A6A4FF00FFFF00FFFF00FFFF00FF + C2A6A4FFF1E5FFF1E5018A02D9E2C3D9E2C3018A02D9E2C3018A02FFF1E5FFF1 + E5C2A6A4FF00FFFF00FFFF00FFFF00FFC2A6A4FFF0E2FFF0E2D9E1C1018A0201 + 8A02D9E1C1DDCFC2DDCFC2DDCFC2DDCFC2C2A6A4FF00FFFF00FFFF00FFFF00FF + C2A6A4FFEEDEFFEEDEFFEEDEFFEEDEFFEEDEFFEEDEC5B5A9C3B4A8C2B3A7C1B2 + A6C2A6A4FF00FFFF00FFFF00FFFF00FFC2A6A4FFECDAFFECDAFFECDAFFECDAFF + ECDAFFECDAB0A296B0A296B0A296B0A296C2A6A4FF00FFFF00FFFF00FFFF00FF + C2A6A4FFEAD7FFEAD7FFEAD7FFEAD7FFEAD7C9B9ACFBF8F4FBF8F4E6DAD9C2A6 + A4FF00FFFF00FFFF00FFFF00FFFF00FFC2A6A4FFE8D3FFE8D3FFE8D3FFE8D3FF + E8D3C9B9ACFBF8F4DFCEC7C2A6A4FF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + C2A6A4FFE6D0FFE6D0FFE6D0FFE6D0FFE6D0C9B9ACDFCEC7C2A6A4FF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFC2A6A4C2A6A4C2A6A4C2A6A4C2A6A4C2 + A6A4C2A6A4C2A6A4FF00FFFF00FFFF00FFFF00FFFF00FFFF00FF} + TabOrder = 0 + OnClick = bbAccountsRefreshClick + end + end + end + object pcAccountsOptions: TPageControl + Left = 405 + Top = 66 + Width = 415 + Height = 516 + ActivePage = tsMultiSelectAccounts + Align = alClient + TabOrder = 2 + object tsAccountOperations: TTabSheet + Caption = 'Account Operations' + object dgAccountOperations: TDrawGrid + Left = 0 + Top = 0 + Width = 407 + Height = 488 + Align = alClient + TabOrder = 0 + end + end + object tsMultiSelectAccounts: TTabSheet + Caption = 'Selected Accounts For Batch Operation' + ImageIndex = 1 + object dgSelectedAccounts: TDrawGrid + Left = 41 + Top = 31 + Width = 320 + Height = 431 + Align = alLeft + TabOrder = 0 + end + object pnlSelectedAccountsTop: TPanel + Left = 0 + Top = 0 + Width = 407 + Height = 31 + Align = alTop + BevelOuter = bvNone + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -13 + Font.Name = 'Tahoma' + Font.Style = [fsBold] + ParentFont = False + TabOrder = 1 + object Label15: TLabel + Left = 41 + Top = 4 + Width = 361 + Height = 16 + Caption = 'Select multiple accounts to execute massive operations' + Color = clBtnFace + ParentColor = False + end + end + object pnlSelectedAccountsBottom: TPanel + Left = 0 + Top = 462 + Width = 407 + Height = 26 + Align = alBottom + BevelOuter = bvNone + TabOrder = 2 + object Label20: TLabel + Left = 41 + Top = 6 + Width = 48 + Height = 13 + Caption = 'Accounts:' + Color = clBtnFace + ParentColor = False + end + object lblSelectedAccountsCount: TLabel + Left = 96 + Top = 6 + Width = 18 + Height = 13 + Caption = '000' + Color = clBtnFace + ParentColor = False + end + object Label22: TLabel + Left = 156 + Top = 6 + Width = 88 + Height = 13 + Caption = 'Accounts Balance:' + Color = clBtnFace + ParentColor = False + end + object lblSelectedAccountsBalance: TLabel + Left = 250 + Top = 6 + Width = 18 + Height = 13 + Caption = '000' + Color = clBtnFace + ParentColor = False + end + end + object pnlSelectedAccountsLeft: TPanel + Left = 0 + Top = 31 + Width = 41 + Height = 431 + Align = alLeft + BevelOuter = bvNone + TabOrder = 3 + object sbSelectedAccountsAdd: TSpeedButton + Left = 2 + Top = 0 + Width = 33 + Height = 31 + Caption = '>' + OnClick = sbSelectedAccountsAddClick + end + object sbSelectedAccountsAddAll: TSpeedButton + Left = 2 + Top = 37 + Width = 33 + Height = 31 + Caption = '>>' + OnClick = sbSelectedAccountsAddAllClick + end + object sbSelectedAccountsDel: TSpeedButton + Left = 2 + Top = 74 + Width = 33 + Height = 31 + Caption = '<' + OnClick = sbSelectedAccountsDelClick + end + object sbSelectedAccountsDelAll: TSpeedButton + Left = 2 + Top = 111 + Width = 33 + Height = 31 + Caption = '<<' + OnClick = sbSelectedAccountsDelAllClick + end + end + object bbSelectedAccountsOperation: TBitBtn + Left = 367 + Top = 31 + Width = 75 + Height = 61 + Caption = 'Operations' + Glyph.Data = { + F6060000424DF606000000000000360000002800000018000000180000000100 + 180000000000C0060000120B0000120B00000000000000000000FF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FF019ACF019ACF019ACF019ACFFF00FFFF00FFFF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FF0C8518FF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FF0D9FD18BD4EE6BD3F845C0ED28B0E0019ACF01 + 9ACF019ACF019ACFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF0C85180C8518 + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF069CD076C8E5A9E9FE6DD8 + FF75DBFF77DCFF77DBFF63D1F930B3E3029BD0019ACF019ACF019ACF019ACFFF + 00FF0C85181399220C8518FF00FFFF00FFFF00FFFF00FFFF00FFFF00FF019ACF + 34AFD9BCE9F86ED8FF6FD8FE70D8FE70D8FE71D8FF0C85180C85180C85180C85 + 180C85180C85180C85180C85181DAC31139A220C8518FF00FFFF00FFFF00FFFF + 00FFFF00FF019ACF1FA9D68FD3EB97E4FF6FD9FE71D9FE71D9FE71D9FE0C8518 + 57E38851DD7E4AD77443D0693BC95E34C1522BBA4725B33C1EAE33149B230C85 + 18FF00FFFF00FFFF00FFFF00FF019ACF31B1DC49B7DEBDEEFB71DDFE77DEFE77 + DEFE77DEFE0C85185EE89059E48953DE804CD87645D16C3DCA6035C2542DBB49 + 26B53F1FAF35149B250C8518FF00FFFF00FFFF00FF019ACF52C2E71DA7D5ADE2 + F38FE8FF7CE2FE7CE3FE7CE3FE0C851861EB955FE9925AE58B54DF824DD97846 + D26D3ECB6237C4562FBD4C27B64021B037159B250C8518FF00FFFF00FF019ACF + 60CAEF1FA8D85EC1E1C2E6ED8ACEE08FCFE18ECFE10C851861EB9561EB955FEA + 935CE58D56E0844FDB7A48D47040CD6538C65931BF4D1DA3320C8518FF00FFFF + 00FFFF00FF019ACF65CFF53EB7E52CA9D4C5EFF8ACF3FEA5F2FFA5F2FF0C8518 + 61EB9561EB9561EB9561EB945CE68E57E18650DC7C49D57242CE6727AD410C85 + 18FF00FFFF00FFFF00FFFF00FF019ACF69D1F855C4F32A9CC673CBE7D6FEFDB1 + FBFDB2FBFD0C85180C85180C85180C85180C85180C85180C85180C851852DD7F + 32B6500C851898FAFF019ACFFF00FFFF00FFFF00FF019ACF77D5FC5CC8FB748E + A224A8D5B9E7F3D5F5F9D5F6F9D6F6FADCFAFBCDFDFCB9FCFCAFFAFCB0FAFCB1 + FAFC0C85183ABE5C0C85189FFCFFA4FFFF43C1E2019ACFFF00FFFF00FF019ACF + 8BDBFF5FCDFFB7898973C3DD18A2D218A2D216A2D215A1D21AA4D391D7EBEBFE + FDDBFDFCC5FBFBC2FBFB0C85180C851883E4F3B6FDFFBAFFFFB5FCFD019ACFFF + 00FFFF00FF019ACF99E2FF67D3FFB88989FEF5ECFDF3EBF0EFEAE5EBE8D6E5E6 + A4D2E025A6D34DB9DDE5F8FBF5FDFCEBFCFB0C8518C4FBFF9CE4F2DAFEFFD9FE + FFE3FFFFADE9F5019ACFFF00FF019ACF9FE9FF70DCFFB88989FEF3E9FFF2E6FE + F3E9FEF3E9FEF3E9FEF3E9D4E4E439ADD422A5D49DD8ECF1F9FBEEEFEFE9FDFF + CEEEF7F8FFFFF7FFFFFEFFFFE9F9FD019ACFFF00FF019ACFA7EFFF76E5FFB889 + 89FFF2E5FFF0E2FFF2E5FFF2E5FFF2E5FFF2E5FFF2E5EAEBE38EC9DA44B0D501 + 9ACF019ACF019ACF019ACF019ACF019ACF019ACF019ACF019ACFFF00FF019ACF + ABF6FF7EEDFFB88989FFF0E2FFEFDFFFF0E2FFF0E2FFF0E2FFF0E2FFF0E2FEEE + E0FBECDEFAEBDEF6E6D9B8898993F7FF019ACFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FF019ACFC7FFFF82F5FFB88989FFEEDFFFECDBFFEEDFFFEEDFFFEEDF + FFEEDFF9E8D9DECCC1D9CABDCFBDB4C8B3ACB88989B5FFFF019ACFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FF019ACFA4E0F0A0FDFFB88989FFECDBFFEBD8FF + ECDBFFECDBFFECDBFFECDBF5E2D2C4ABA7C2A8A5BBA39FC2AFA9B88989019ACF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF019ACFECFFFFB889 + 89FFEBD8FFEAD5FFEBD8FFEBD8FFEBD8FFEBD8FFEBD8D9C8C5FEFEFDFEF6EFDE + C9C0B88989FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + FF00FF019ACFB88989FFE9D5FFE8D3FFE9D5FFE9D5FFE9D5FFE9D5FFE9D5C6AD + A9FEF8F2E8D4CACD9999FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFB88989FFE7D1FFE7D0FFE7D1FFE7D1FFE7D1 + FFE7D1E7CEBFD3BFB9E8D5CCCD9999FF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFB88989FFE6CFFFE6CFFF + E6CFFFE6CFFFE6CFFFE6CFD5BBB2E0CCC5CD9999FF00FFFF00FFFF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFB889 + 89B88989B88989B88989B88989B88989B88989B88989B88989FF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF} + Layout = blGlyphTop + TabOrder = 4 + OnClick = bbSelectedAccountsOperationClick + end + end + end +end diff --git a/src/gui-classic/Frames/UFrameAccountExplorer.pas b/src/gui-classic/Frames/UFrameAccountExplorer.pas new file mode 100644 index 000000000..c99b7192c --- /dev/null +++ b/src/gui-classic/Frames/UFrameAccountExplorer.pas @@ -0,0 +1,529 @@ +unit UFrameAccountExplorer; + +interface + +uses + Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, + Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ComCtrls, Vcl.Grids, + Vcl.StdCtrls, Vcl.Buttons, Vcl.ExtCtrls, + UBaseTypes, + UGridUtils; + +type + TFrameAccountExplorer = class(TFrame) + Splitter1: TSplitter; + pnlMyAccountsTop: TPanel; + Label18: TLabel; + sbSearchAccount: TSpeedButton; + cbMyPrivateKeys: TComboBox; + cbExploreMyAccounts: TCheckBox; + ebFindAccountNumber: TEdit; + bbChangeKeyName: TBitBtn; + cbFilterAccounts: TCheckBox; + ebFilterAccountByBalanceMin: TEdit; + ebFilterAccountByBalanceMax: TEdit; + pnlAccounts: TPanel; + dgAccounts: TDrawGrid; + pnlAccountsInfo: TPanel; + Label17: TLabel; + Label19: TLabel; + lblAccountsCount: TLabel; + lblAccountsBalance: TLabel; + bbAccountsRefresh: TBitBtn; + pcAccountsOptions: TPageControl; + tsAccountOperations: TTabSheet; + dgAccountOperations: TDrawGrid; + tsMultiSelectAccounts: TTabSheet; + dgSelectedAccounts: TDrawGrid; + pnlSelectedAccountsTop: TPanel; + Label15: TLabel; + pnlSelectedAccountsBottom: TPanel; + Label20: TLabel; + lblSelectedAccountsCount: TLabel; + Label22: TLabel; + lblSelectedAccountsBalance: TLabel; + pnlSelectedAccountsLeft: TPanel; + sbSelectedAccountsAdd: TSpeedButton; + sbSelectedAccountsAddAll: TSpeedButton; + sbSelectedAccountsDel: TSpeedButton; + sbSelectedAccountsDelAll: TSpeedButton; + bbSelectedAccountsOperation: TBitBtn; + procedure bbAccountsRefreshClick(Sender: TObject); + procedure cbMyPrivateKeysChange(Sender: TObject); + procedure dgAccountsClick(Sender: TObject); + + procedure dgAccountsColumnMoved(Sender: TObject; FromIndex, + ToIndex: Integer); + procedure dgAccountsFixedCellClick(Sender: TObject; ACol, ARow: Integer); + + procedure sbSearchAccountClick(Sender: TObject); + + procedure cbExploreMyAccountsClick(Sender: TObject); + + + procedure ebFindAccountNumberChange(Sender: TObject); + procedure ebFindAccountNumberExit(Sender: TObject); + + procedure bbChangeKeyNameClick(Sender: TObject); + + procedure sbSelectedAccountsAddClick(Sender: TObject); + procedure sbSelectedAccountsAddAllClick(Sender: TObject); + procedure sbSelectedAccountsDelClick(Sender: TObject); + procedure sbSelectedAccountsDelAllClick(Sender: TObject); + procedure bbSelectedAccountsOperationClick(Sender: TObject); + + procedure ebFilterAccountByBalanceMinExit(Sender: TObject); + procedure ebFilterAccountByBalanceMinKeyPress(Sender: TObject; + var Key: Char); + procedure cbFilterAccountsClick(Sender: TObject); + procedure ebFilterAccountByBalanceMaxExit(Sender: TObject); + procedure ebFilterAccountByBalanceMaxKeyPress(Sender: TObject; + var Key: Char); + + private + { Private declarations } + FAccountsGrid : TAccountsGrid; + FSelectedAccountsGrid : TAccountsGrid; + + + FMinAccountBalance : Int64; + FMaxAccountBalance : Int64; + + FLastAccountsGridInvalidateTC : TTickCount; + + procedure ebFilterAccountByBalanceExitShared( Sender : TObject ); + procedure ebFilterAccountByBalanceKeyPressShared( Sender : TObject; var Key : Char ); + + function DoUpdateAccountsFilter: Boolean; + + + public + { Public declarations } + + procedure UpdateAccounts(RefreshData : Boolean); + procedure UpdatePrivateKeys; + + procedure OnAccountsGridUpdatedData(Sender : TObject); + Procedure OnSelectedAccountsGridUpdated(Sender : TObject); + + + property AccountsGrid : TAccountsGrid read FAccountsGrid write FAccountsGrid; + property SelectedAccountsGrid : TAccountsGrid read FSelectedAccountsGrid write FSelectedAccountsGrid; + + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + end; + +implementation + +{$R *.dfm} + +uses + UFRMWallet, UConst, UPCOrderedLists, UFRMOperation, + USettings, UFRMAccountSelect, UAccounts, + UPCDataTypes, UWallet, UCrypto; + +procedure TFrameAccountExplorer.OnAccountsGridUpdatedData(Sender: TObject); +begin + if FAccountsGrid.IsUpdatingData then begin + lblAccountsCount.Caption := '(Calculating)'; + lblAccountsBalance.Caption := '(Calculating)'; + end else begin + lblAccountsCount.Caption := IntToStr(FAccountsGrid.AccountsCount); + lblAccountsBalance.Caption := TAccountComp.FormatMoney(FAccountsGrid.AccountsBalance); + end; +end; + +procedure TFrameAccountExplorer.OnSelectedAccountsGridUpdated(Sender: TObject); +begin + lblSelectedAccountsCount.Caption := Inttostr(FSelectedAccountsGrid.AccountsCount); + lblSelectedAccountsBalance.Caption := TAccountComp.FormatMoney( FSelectedAccountsGrid.AccountsBalance ); +end; + +constructor TFrameAccountExplorer.Create(AOwner: TComponent); +begin + inherited Create( AOwner ); + + FMinAccountBalance := 0; + FMaxAccountBalance := CT_MaxWalletAmount; + + FLastAccountsGridInvalidateTC := TPlatform.GetTickCount; + + + // cannot set properties here that interact with FRMWallet because + // FRMWallet not yet created. + // problem code below, moved back to FRMWallet.FormCreate +{ + pcAccountsOptions.ActivePage := tsAccountOperations; + + // problem code: + cbExploreMyAccounts.Checked:=True; // By default +} +end; + +destructor TFrameAccountExplorer.Destroy; +begin + + inherited Destroy; +end; + +procedure TFrameAccountExplorer.bbAccountsRefreshClick(Sender: TObject); +begin + UpdateAccounts(true); +end; + +procedure TFrameAccountExplorer.bbChangeKeyNameClick(Sender: TObject); +var i : Integer; + name : String; +begin + if (cbMyPrivateKeys.ItemIndex<0) then exit; + i := PtrInt(cbMyPrivateKeys.Items.Objects[cbMyPrivateKeys.ItemIndex]); + if (i<0) Or (i>=FRMWallet.WalletKeys.Count) then raise Exception.Create('Must select a Key'); + name := FRMWallet.WalletKeys.Key[i].Name; + if InputQuery('Change Key name','Input new name',name) then begin + FRMWallet.WalletKeys.SetName(i,name); + end; + UpdatePrivateKeys; +end; + +procedure TFrameAccountExplorer.bbSelectedAccountsOperationClick(Sender: TObject); +var l : TOrderedCardinalList; +begin + FRMWallet.CheckIsReady; + if FSelectedAccountsGrid.AccountsCount<=0 then raise Exception.Create('Must select at least 1 account'); + With TFRMOperation.Create(Self) do + Try + l := FSelectedAccountsGrid.LockAccountsList; + try + SenderAccounts.CopyFrom(l); + finally + FSelectedAccountsGrid.UnlockAccountsList; + end; + DefaultFee := TSettings.DefaultFee; + WalletKeys := FRMWallet.WalletKeys; + ShowModal; + Finally + Free; + End; +end; + +procedure TFrameAccountExplorer.cbExploreMyAccountsClick(Sender: TObject); +begin + cbMyPrivateKeys.Enabled := cbExploreMyAccounts.Checked; + UpdateAccounts(true); + FRMWallet.UpdateOperations; +end; + +procedure TFrameAccountExplorer.cbFilterAccountsClick(Sender: TObject); +begin + If not DoUpdateAccountsFilter then UpdateAccounts(true); +end; + +procedure TFrameAccountExplorer.cbMyPrivateKeysChange(Sender: TObject); +begin + UpdateAccounts(true); +end; + +procedure TFrameAccountExplorer.dgAccountsClick(Sender: TObject); +begin + FRMWallet.UpdateOperations; +end; + +procedure TFrameAccountExplorer.dgAccountsColumnMoved(Sender: TObject; FromIndex, ToIndex: Integer); +begin + TSettings.Save; +end; + +procedure TFrameAccountExplorer.dgAccountsFixedCellClick(Sender: TObject; ACol, + ARow: Integer); +begin + TSettings.Save; +end; + +procedure TFrameAccountExplorer.ebFindAccountNumberChange(Sender: TObject); +Var an : Cardinal; + LAccountNameRawValue : TRawBytes; + LErrors : String; + LAccNames : TOrderedRawList; +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 + LAccountNameRawValue.FromString(ebFindAccountNumber.Text); + LAccNames := TOrderedRawList.Create; + Try + if FRMWallet.Node.Bank.SafeBox.FindAccountsStartingByName(LAccountNameRawValue,LAccNames,1)>0 then begin + an := LAccNames.GetTag(0); + 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; + Finally + LAccNames.Free; + End; + end; +end; + +procedure TFrameAccountExplorer.ebFindAccountNumberExit(Sender: TObject); +begin + ebFindAccountNumber.Text := ''; +end; + +procedure TFrameAccountExplorer.sbSearchAccountClick(Sender: TObject); +Var F : TFRMAccountSelect; +begin + F := TFRMAccountSelect.Create(Self); + try + F.Node := FRMWallet.Node; + F.WalletKeys := FRMWallet.WalletKeys; + F.ShowModal; + finally + F.Free; + end; +end; + +procedure TFrameAccountExplorer.sbSelectedAccountsAddAllClick(Sender: TObject); +Var lsource,ltarget : TOrderedCardinalList; + i : Integer; +begin + lsource := FAccountsGrid.LockAccountsList; + Try + ltarget := FSelectedAccountsGrid.LockAccountsList; + Try + for i := 0 to lsource.Count-1 do begin + if FRMWallet.WalletKeys.IndexOfAccountKey(FRMWallet.Node.Bank.SafeBox.Account(lsource.Get(i)).accountInfo.accountKey)<0 then raise Exception.Create(Format('You cannot operate with account %d because private key not found in your wallet',[lsource.Get(i)])); + ltarget.Add(lsource.Get(i)); + end; + Finally + FSelectedAccountsGrid.UnlockAccountsList; + End; + Finally + FAccountsGrid.UnlockAccountsList; + End; +end; + +procedure TFrameAccountExplorer.sbSelectedAccountsAddClick(Sender: TObject); +Var l, selected : TOrderedCardinalList; + an : Int64; + i : Integer; +begin + an := FAccountsGrid.AccountNumber(dgAccounts.Row); + if (an<0) then raise Exception.Create('No account selected'); + if FRMWallet.WalletKeys.IndexOfAccountKey(FRMWallet.Node.Bank.SafeBox.Account(an).accountInfo.accountkey)<0 then + raise Exception.Create(Format('You cannot add %s account because private key not found in your wallet.'#10+#10+'You''re not the owner!', + [TAccountComp.AccountNumberToAccountTxtNumber(an)])); + // Add + l := FSelectedAccountsGrid.LockAccountsList; + selected := TOrderedCardinalList.Create; + Try + FAccountsGrid.SelectedAccounts(selected); + for i := 0 to selected.Count-1 do begin + l.Add(selected.Get(i)); + end; + Finally + selected.Free; + FSelectedAccountsGrid.UnlockAccountsList; + End; +end; + +procedure TFrameAccountExplorer.sbSelectedAccountsDelAllClick(Sender: TObject); +Var l : TOrderedCardinalList; +begin + l := FSelectedAccountsGrid.LockAccountsList; + try + l.Clear; + finally + FSelectedAccountsGrid.UnlockAccountsList; + end; +end; + +procedure TFrameAccountExplorer.sbSelectedAccountsDelClick(Sender: TObject); +Var an : Int64; + l : TOrderedCardinalList; +begin + l := FSelectedAccountsGrid.LockAccountsList; + try + an := FSelectedAccountsGrid.AccountNumber(dgSelectedAccounts.Row); + if an>=0 then l.Remove(an); + finally + FSelectedAccountsGrid.UnlockAccountsList; + end; +end; + +procedure TFrameAccountExplorer.ebFilterAccountByBalanceExitShared( Sender : TObject ); +begin + DoUpdateAccountsFilter; +end; + +procedure TFrameAccountExplorer.ebFilterAccountByBalanceKeyPressShared( Sender : TObject; var Key : Char ); +begin + if key=#13 then DoUpdateAccountsFilter; +end; + +procedure TFrameAccountExplorer.ebFilterAccountByBalanceMinExit(Sender: TObject); +begin + ebFilterAccountByBalanceExitShared( Sender );; +end; + +procedure TFrameAccountExplorer.ebFilterAccountByBalanceMaxExit( + Sender: TObject); +begin + ebFilterAccountByBalanceExitShared( Sender );; +end; + +procedure TFrameAccountExplorer.ebFilterAccountByBalanceMinKeyPress(Sender: TObject; + var Key: Char); +begin + ebFilterAccountByBalanceKeyPressShared( Sender, Key ); +end; + +procedure TFrameAccountExplorer.ebFilterAccountByBalanceMaxKeyPress( + Sender: TObject; var Key: Char); +begin + ebFilterAccountByBalanceKeyPressShared( Sender, Key ); +end; + +function TFrameAccountExplorer.DoUpdateAccountsFilter: Boolean; +Var m,bmin,bmax:Int64; + doupd : Boolean; +begin + if FRMWallet.Updating then exit; + FRMWallet.Updating := true; + Try + If Not TAccountComp.TxtToMoney(ebFilterAccountByBalanceMin.Text,bmin) then bmin := 0; + If not TAccountComp.TxtToMoney(ebFilterAccountByBalanceMax.Text,bmax) then bmax := CT_MaxWalletAmount; + if (bmaxbmax then bmin := 0; + doupd := (bmin<>FMinAccountBalance) Or (bmax<>FMaxAccountBalance); + if bmin>0 then + ebFilterAccountByBalanceMin.Text:=TAccountComp.FormatMoney(bmin) + else ebFilterAccountByBalanceMin.Text := ''; + if bmax1000 then begin + FLastAccountsGridInvalidateTC := TPlatform.GetTickCount; + dgAccounts.Invalidate; + end; + exit; + end; + + LApplyfilter := (cbFilterAccounts.Checked) and ((FMinAccountBalance>0) Or ((FMaxAccountBalance=0))); + if (Not cbExploreMyAccounts.Checked) And (not LApplyfilter) then begin + FAccountsGrid.AccountsGridDatasource := acds_Node; + FAccountsGrid.UpdateData; + end else begin + LFilters := FAccountsGrid.AccountsGridFilter; + LFilters.MinBalance := FMinAccountBalance; + LFilters.MaxBalance := FMaxAccountBalance; + if cbExploreMyAccounts.Checked then begin + //FNode.Bank.SafeBox.StartThreadSafe; + try + LFilters.OrderedAccountsKeyList := FRMWallet.WalletKeys.AccountsKeyList; + if cbMyPrivateKeys.ItemIndex>0 then begin + i := PtrInt(cbMyPrivateKeys.Items.Objects[cbMyPrivateKeys.ItemIndex]); + if (i>=0) And (i=0) then last_i := PtrInt(cbMyPrivateKeys.Items.Objects[cbMyPrivateKeys.ItemIndex]) + else last_i := -1; + cbMyPrivateKeys.items.BeginUpdate; + Try + cbMyPrivateKeys.Items.Clear; + For i:=0 to FRMWallet.WalletKeys.Count-1 do begin + wk := FRMWallet.WalletKeys.Key[i]; + if (wk.Name='') then begin + s := 'Sha256='+TCrypto.ToHexaString( TCrypto.DoSha256( TAccountComp.AccountKey2RawString(wk.AccountKey) ) ); + end else begin + s := wk.Name; + end; + if Not Assigned(wk.PrivateKey) then begin + if Length(wk.CryptedKey)>0 then s:=s+' (**NEED PASSWORD**)' + else s:=s+' (**PUBLIC KEY ONLY**)'; + end; + cbMyPrivateKeys.Items.AddObject(s,TObject(i)); + end; + cbMyPrivateKeys.Sorted := true; + cbMyPrivateKeys.Sorted := false; + cbMyPrivateKeys.Items.InsertObject(0,'(All my private keys)',TObject(-1)); + Finally + cbMyPrivateKeys.Items.EndUpdate; + End; + last_i := cbMyPrivateKeys.Items.IndexOfObject(TObject(last_i)); + if last_i<0 then last_i := 0; + if cbMyPrivateKeys.Items.Count>last_i then cbMyPrivateKeys.ItemIndex := last_i + else if cbMyPrivateKeys.Items.Count>=0 then cbMyPrivateKeys.ItemIndex := 0; +end; + + +end. diff --git a/src/gui-classic/Frames/UFrameBlockExplorer.dfm b/src/gui-classic/Frames/UFrameBlockExplorer.dfm new file mode 100644 index 000000000..7fbd7b74b --- /dev/null +++ b/src/gui-classic/Frames/UFrameBlockExplorer.dfm @@ -0,0 +1,92 @@ +object FrameBlockChainExplorer: TFrameBlockChainExplorer + Left = 0 + Top = 0 + Width = 782 + Height = 489 + TabOrder = 0 + object Panel2: TPanel + Left = 0 + Top = 0 + Width = 782 + Height = 41 + Align = alTop + BevelOuter = bvNone + TabOrder = 0 + object Label9: TLabel + Left = 11 + Top = 10 + Width = 102 + Height = 13 + Caption = 'Filter by blocks range' + Color = clBtnFace + ParentColor = False + end + object lblHashRateBackBlocks: TLabel + Left = 280 + Top = 10 + Width = 104 + Height = 13 + Caption = 'HashRate back blocks' + Color = clBtnFace + ParentColor = False + end + object lblHashRateBackBlocks1: TLabel + Left = 463 + Top = 10 + Width = 24 + Height = 13 + Caption = 'Units' + Color = clBtnFace + ParentColor = False + end + object ebBlockChainBlockStart: TEdit + Left = 125 + Top = 7 + Width = 57 + Height = 21 + TabOrder = 0 + OnExit = ebBlockChainBlockStartExit + OnKeyPress = ebBlockChainBlockStartKeyPress + end + object ebBlockChainBlockEnd: TEdit + Left = 185 + Top = 7 + Width = 57 + Height = 21 + TabOrder = 1 + end + object ebHashRateBackBlocks: TEdit + Left = 392 + Top = 7 + Width = 56 + Height = 21 + TabOrder = 2 + OnExit = ebHashRateBackBlocksExit + OnKeyPress = ebHashRateBackBlocksKeyPress + end + object cbHashRateUnits: TComboBox + Left = 496 + Top = 7 + Width = 56 + Height = 21 + Style = csDropDownList + ItemIndex = 1 + TabOrder = 3 + Text = 'Mh/s' + OnClick = cbHashRateUnitsClick + Items.Strings = ( + 'Kh/s' + 'Mh/s' + 'Gh/s' + 'Th/s') + end + end + object dgBlockChainExplorer: TDrawGrid + Left = 0 + Top = 41 + Width = 782 + Height = 448 + Align = alClient + TabOrder = 1 + end +end diff --git a/src/gui-classic/Frames/UFrameBlockExplorer.pas b/src/gui-classic/Frames/UFrameBlockExplorer.pas new file mode 100644 index 000000000..9c209c0da --- /dev/null +++ b/src/gui-classic/Frames/UFrameBlockExplorer.pas @@ -0,0 +1,160 @@ +unit UFrameBlockExplorer; + +interface + +uses + Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, + Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Grids, Vcl.StdCtrls, + Vcl.ExtCtrls, + USettings; + +type + TFrameBlockChainExplorer = class(TFrame) + Panel2: TPanel; + Label9: TLabel; + lblHashRateBackBlocks: TLabel; + lblHashRateBackBlocks1: TLabel; + ebBlockChainBlockStart: TEdit; + ebBlockChainBlockEnd: TEdit; + ebHashRateBackBlocks: TEdit; + cbHashRateUnits: TComboBox; + dgBlockChainExplorer: TDrawGrid; + procedure cbHashRateUnitsClick(Sender: TObject); + procedure ebHashRateBackBlocksExit(Sender: TObject); + procedure ebHashRateBackBlocksKeyPress(Sender: TObject; var Key: char); + procedure ebBlockChainBlockStartExit(Sender: TObject); + procedure ebBlockChainBlockStartKeyPress(Sender: TObject; var Key: Char); + + private + { Private declarations } + public + { Public declarations } + procedure ChangeHashRateUnits( ParaHashRateAs : TShowHashRateAs ); + + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + end; + +implementation + +{$R *.dfm} + +uses + UFRMWallet; + +constructor TFrameBlockChainExplorer.Create(AOwner: TComponent); +begin + inherited Create( AOwner ); + + cbHashRateUnits.Items.Clear; + cbHashRateUnits.Items.Add('h/s'); + cbHashRateUnits.Items.Add('Kh/s'); + cbHashRateUnits.Items.Add('Mh/s'); + cbHashRateUnits.Items.Add('Gh/s'); + cbHashRateUnits.Items.Add('Th/s'); + cbHashRateUnits.Items.Add('Ph/s'); + cbHashRateUnits.Items.Add('Eh/s'); + +end; + +destructor TFrameBlockChainExplorer.Destroy; +begin + + inherited Destroy; +end; + +procedure TFrameBlockChainExplorer.ebBlockChainBlockStartExit(Sender: TObject); +var bstart,bend : Int64; +begin + with FRMWallet do + begin + + If Updating then exit; + Updating := True; + Try + bstart := StrToInt64Def(ebBlockChainBlockStart.Text,-1); + bend := StrToInt64Def(ebBlockChainBlockEnd.Text,-1); + BlockChainGrid.SetBlocks(bstart,bend); + if BlockChainGrid.BlockStart>=0 then ebBlockChainBlockStart.Text := Inttostr(BlockChainGrid.BlockStart) else ebBlockChainBlockStart.Text := ''; + if BlockChainGrid.BlockEnd>=0 then ebBlockChainBlockEnd.Text := Inttostr(BlockChainGrid.BlockEnd) else ebBlockChainBlockEnd.Text := ''; + Finally + Updating := false; + End; + + end; +end; + +procedure TFrameBlockChainExplorer.ebBlockChainBlockStartKeyPress(Sender: TObject; + var Key: Char); +begin + if key=#13 then ebBlockChainBlockStartExit(Nil); +end; + +procedure TFrameBlockChainExplorer.ebHashRateBackBlocksKeyPress(Sender: TObject; var Key: char); +begin + if Key=#13 then ebHashRateBackBlocksExit(Nil); +end; + +procedure TFrameBlockChainExplorer.ebHashRateBackBlocksExit(Sender: TObject); +var i : Integer; +begin + with FRMWallet do + begin + + If Updating then exit; + Updating := True; + Try + i := StrToIntDef(ebHashRateBackBlocks.Text,-1); + BlockChainGrid.HashRateAverageBlocksCount:=i; + TSettings.HashRateAvgBlocksCount := BlockChainGrid.HashRateAverageBlocksCount; + Finally + ebHashRateBackBlocks.Text := IntToStr(BlockChainGrid.HashRateAverageBlocksCount); + Updating := false; + End; + + end; +end; + +procedure TFrameBlockChainExplorer.cbHashRateUnitsClick(Sender: TObject); +begin + with FRMWallet do + begin + + If Updating then Exit; + Updating := True; + Try + case cbHashRateUnits.ItemIndex of + 0 : BlockChainGrid.HashRateAs := hr_Unit; + 1 : BlockChainGrid.HashRateAs := hr_Kilo; + 2 : BlockChainGrid.HashRateAs := hr_Mega; + 3 : BlockChainGrid.HashRateAs := hr_Giga; + 4 : BlockChainGrid.HashRateAs := hr_Tera; + 5 : BlockChainGrid.HashRateAs := hr_Peta; + 6 : BlockChainGrid.HashRateAs := hr_Exa; + else BlockChainGrid.HashRateAs := hr_Mega; + end; + TSettings.ShowHashRateAs := BlockChainGrid.HashRateAs; + Finally + Updating := false; + End; + + end; +end; + +procedure TFrameBlockChainExplorer.ChangeHashRateUnits( ParaHashRateAs : TShowHashRateAs ); +begin + Case ParaHashRateAs of + hr_Unit : cbHashRateUnits.ItemIndex:=0; + hr_Kilo : cbHashRateUnits.ItemIndex:=1; + hr_Mega : cbHashRateUnits.ItemIndex:=2; + hr_Giga : cbHashRateUnits.ItemIndex:=3; + hr_Tera : cbHashRateUnits.ItemIndex:=4; + hr_Peta : cbHashRateUnits.ItemIndex:=5; + hr_Exa : cbHashRateUnits.ItemIndex:=6; + else + cbHashRateUnits.ItemIndex:=-1; + end; +end; + + +end. diff --git a/src/gui-classic/Frames/UFrameInfo.dfm b/src/gui-classic/Frames/UFrameInfo.dfm new file mode 100644 index 000000000..44aa7475e --- /dev/null +++ b/src/gui-classic/Frames/UFrameInfo.dfm @@ -0,0 +1,415 @@ +object FrameInfo: TFrameInfo + Left = 0 + Top = 0 + Width = 924 + Height = 108 + TabOrder = 0 + object Splitter1: TSplitter + Left = 75 + Top = 0 + Height = 108 + ResizeStyle = rsUpdate + ExplicitLeft = 160 + ExplicitTop = 48 + ExplicitHeight = 100 + end + object Splitter2: TSplitter + Left = 318 + Top = 0 + Height = 108 + ResizeStyle = rsUpdate + ExplicitLeft = 408 + ExplicitTop = 64 + ExplicitHeight = 100 + end + object Splitter3: TSplitter + Left = 561 + Top = 0 + Height = 108 + ResizeStyle = rsUpdate + ExplicitLeft = 560 + ExplicitHeight = 104 + end + object Panel1: TPanel + Left = 0 + Top = 0 + Width = 75 + Height = 108 + Align = alLeft + BevelKind = bkTile + BevelOuter = bvNone + Caption = ' ' + TabOrder = 0 + object Image1: TImage + Left = 0 + Top = 0 + Width = 71 + Height = 104 + Align = alClient + AutoSize = True + Center = True + Picture.Data = { + 0954506E67496D61676589504E470D0A1A0A0000000D49484452000000400000 + 00400806000000AA6971DE0000000467414D410000B18F0BFC61050000000970 + 48597300000EC200000EC20115284A800000001874455874536F667477617265 + 007061696E742E6E657420342E312E36FD4E09E800000AD54944415478DAD55B + 0B7854C515FE67EEDD17848780402860B21BE4258A8116FD1004A4F889852282 + A808A2541113146DB5AD521A3EABD54AA186243E2A55D17E060111A42A5A9487 + F8E04D4185920DB18809280884ECFBCEF4DC0D6CB264F766B30F361EF86EF6EE + 3DF3F8FF397BE6CCB9334C4A89944A415FB3BF93B79F4F139733C97A32862C06 + 7402581B6AD9060649FF3C7439C1192A85645F7326BFD2A0ED6AF95DD65E14AC + 0FA4B27B2C1504B84B72BA494DDEC0384613B8218CB116F1D4437DAB26823630 + 897F694C7BAB655E4555B32560FB0B034D7D7CC7C7017C06757A388D324F6647 + C9420290EC7D29C4732D320FBE8389526B1E0410708FF7C434C9E42334D259C9 + 041D950C29F7D3E54FB6CE075F4F94888408A829768CE6600B69B42F3E1FC023 + 50B15B61E27ED3BD07379C5F025EE8D9C1E50B1473C66E4A0FF07A14D06F839C + E662B3C67FCDEE3B702AE504788A728651A97F52D12EE9061F4E842C975CDEDC + E2DEF2AD292380C0CFA2DFFA0206A6A61B70441220BD749961CB77BE92640218 + F314DBE7D3DF07530980B5EB09D6BE07E03D09ED7F1F074384FAC2330702199D + 21ABBF85ACDA118584E0FFB9B6FCF2C71103B8180860CC5BEC2821AD7B52091E + ADBBC17AEB0780526B5CBE8DF320F6BC5AD78B6E436119FB8F332825BC6F4D81 + FCF633830AC553D6BCF2DF254C80A7C8B180387820A5E049949EE3601A393F74 + EFDF58006DCF6BA17BF5CA87A0E6CE08DD7B57DE4A046C69041CE658F2CB1E8F + 9B006F91E37EC9D8DF520D3E08F0AA39502F9B16BAF7AD980851B533746F1AF3 + 3294EE57D5DED0D4EFFE7B2E98BFC6B04E7D8600D36EB7E51D7C359A4E54023C + 2539C3A5901F5070A3843DC8E802F3354F20E97EB0FDC5E0D676A15B51B51DD0 + FC751DED781998C976E66100A2721BA4D0204F7E0D796417F98C4D80EBBB4835 + BB158E21A69965DB6326E0F4B38E8EAA865D64FA99618CAA2D60B971297887DE + C9059F0C21ABD00E6D46605B3164653856C25856E332E57678785F754C04B88B + 1CCB68E427845542A1BDF9BA1228F691E986DA1813087CB914810DF3C852EA2C + 88603E6FCB2F6BE0C81B10E02AB48FE10A5F7DAEA27AE5C3E484EE4E37BA9845 + 73AE85EFBDFCD0544A57012187DA6639374725E040610F4B572EF6D2E8E7D457 + 527A8D8769C453FA8C986E5C4D12DF477320BE2C0DDD13D4EDB6EF9D3F438114 + 1109A0606726851B25610C650E8069EC1270D5926E3C4D1671EA10BCAF8E080B + A824B449342BBCD180802F0AFA9AB33B780F7086EE216D732B98473F0BD4F3CE + CD4AAC6DC15B763454F1965E0F796C7F1D0152FE87A2C4FE417BA84F807B51CE + 24C6518A1F91A8FDEF803AF851431DDFEAA910873E09FF528A51D6FCF20FC209 + 28767C448B9C61E906755E08805C61CD734E0811F04371F6455628E5C94E6335 + 5702F455A3D7AF756E3BBBE244900057916336676C6142BD69D515A621730C55 + 84F35D68FB57258D00A5DF6D300D2D683201B5246853F510394800053E6B69EA + 1B954867F8C5E360FEF97C431DDFFBB3210EAC491E01974C86E9EA7971114052 + 6ACD2BBB85C93FF631BB3B787E8837757D56D42173A15E3AD550C7B3641850FD + 4DF32040A2CA9A5F96C96A4A1C03B8C0B6443B631AFF0694CCDCA8CF85E738BC + 8B073548722444C0A5B7D3CFEE0FF11110EC94DFCEDC85D9D3C1F98B89744472 + 132CBFDA096EB246D5D1576BFEB7EF481A785D4C239E84D27B82A18E110142CA + F1CCBDC8F1171A968712EA49FBDEB0DEFCB6A18A9F5669DAE789F9D9FAC23AF6 + 83F986525A951B47A84604D06CF07B56B3C8BE34D1F436EF3309E6E1868917F8 + B716421EFE2CC61AA3C2066CEDC0BB0C82AA8FBC6A6DB4846FD514886F3E8D4C + 80C073CC55644F380052873D0EB5EFA404C1A5408420C73B04A83912F9B9C49B + CCB5C8BE836680CB1369C77CD36AF00BFBA41B6E43FC95DBE17B33FAC05004B0 + 8E7C807D2F2D73FBC6DD8A6A83951CE0D96C6EB3111A7DEFAADB8C13A7526E60 + 1404EDA18F97C4DB0EEBD41F9609CBD30DF75C64F06F7E0ADAAE4626379D00D7 + 22C716C6F0D3789B52FA4DA570746EBA118744D41C4560D363C1B0BB719AE45A + DD072414069B463E0DA5E70DE9451DF0401CDD0DEDBF6B68ADB132781F135914 + 0EEB16F01259C0B4B809B8652D94768EE88D545722F0C91361DFA9B9F790D33C + E376C813F9D73F02E93B1D7A6ED6C3DB334918E9AD0E3E8F248CE63171EA30E4 + 0F6531830E17B940B780B96401F3E2281DCC1859A76FA74020FA2A5A94BD03DF + DAFBC2BEB3DEBE31F87E21F8BCE63B785FBE1267B38DD2D412B6BB7610BADAD7 + 11DAE1CFE17F6B725CDD6B4CC84FCE623545D91338F8B2782AE03FB902E671AF + 19EAF8373F19E68C180532963B3F07CE40D6BEDE00FF9AE975CF3BE7C2726328 + 6587C0AEC5086CFE734A08A058F81A76624177BBC56C72C6535EE97F174C837F + 6BA873EE3B3C49D19B65D21AF0B659C19719BE0F1F81D8B7A2AE40ABAE304F5C + 096EBB00D2EF868FD60FB232E1B55A03D1D3E4367FA03DA30F7A2C70989DF316 + 2816315D5B0825677474052D00F78BB960015778E364DEBC457B48FD77EB6DB8 + A9432A16706B9B5ABFE077211522A5FCC296EFBC249810F1143996503034A589 + 0CC232652378EBE81B45C4F103F0BD7E5D4A00244C8010CFD86695CF3E9311B2 + 4F648CBFD1A41A6CED61BD535FDC447F5912D8B7128175892D345348C1486B9E + 735D9080A3C57D335A4B4F25594146ACC579F7AB611EB3D850E7DC4D0ECD46A4 + ACB2762AEFAA6FB1AB4B8B173916931FB833D63A948179300D32DE37E15D7E23 + E491DDE9861B8981F934FA41D30C11E02A720C2402B630239BAE27A6D1CF43C9 + BE26BA42C0470EF07230CD9B6EB4E7820F40E3BDACF71D708611A00B59C18744 + C2F046AB208E2CD33E016F7961541DEDE85EF8978D4B37DA48BD5F46A31F4A00 + 8513509C3D948C7B7DA356909149D1DC264395C0DE52043618BF2738EFD0A5D4 + 1405FDCD339D7B2312102461916315E36CAC51453C7B14CCA34B8C546A039CAF + 9A36B1A49C00E0255B5E59989F6B40C0C9C21E0EB322F7E8D9B76815A957FC06 + EA00E35D73DED25F401EDB976ECCF5E11F0F04649F8CFBCBC3F26351B6C8D81F + A4B8E0AFD1AA328D7D054AB7C1519B123E17BCBA034CCE8EF6E4C097725AA41D + A49177892D638AFBA8FD3D06D6704310E3B04CDF0A666913B531AD7207FC6FA6 + 7D1F757DF0CB09FCC448CFA26E93AB29CEEAAC40D94A2A5DC30AB4C982E5B67F + 1B3618D8FD0A021F3F966EDC67C1EFF79831E882BB9D279B44802EAE67730670 + 4DAE0F8B10DB66436D2403242AD641348B00481E637E31D832FBE0FE681A316C + 95CDB95632B98A7E0E3FAE4D42529EA67865942DBFEC5323B598768B7B4BECD7 + 0BC1973386C65FC5340B91A768CDFD4B6B7ED9FAC634633E2FE029CC190E8E15 + 14225D906E788DC811C1C498580F4E34E9C0447549566F55282B295CEE996E94 + 9145EE845F1B6F9D5D51116B89261F993956D8A3754B2E4AC831A62653190F6C + 7D57B814CFDB5A890730ADA249E9E1B84F8DB90AED13B8C29E49F7D921427E90 + 1CF4BDD6BCB2F7E2299FD0B1B95A6B908F4A865946A1734A80EBA74A81F9569F + EF69F6E02177BCF524E5E468CDC28B32B9497D886689E95465EB14033F4E643F + 6735AB0B71F7FEEF13AD2FA96787E5E25EADDC6EFF640E4C918C5D91AC7D87FA + 32966C7D1311BCE4F8F7EEA55D0ABE4D5AAA382587A7839D2EEADEC50B55CF99 + 8FD0C9A0A6B262CD3605B7B6034EEADCA7F4F9434DC1BB19339D4753D1CF9411 + D0405E70B471F9955E4C882CCE652721D13618589117231FE2A1CB0972665592 + 6B15AED3E67D914E77A442FE0F6724BE5B75E29AC60000000049454E44AE4260 + 82} + ExplicitLeft = -31 + ExplicitTop = 177 + ExplicitWidth = 121 + ExplicitHeight = 189 + end + end + object Panel2: TPanel + Left = 78 + Top = 0 + Width = 240 + Height = 108 + Align = alLeft + BevelKind = bkTile + BevelOuter = bvNone + Caption = ' ' + TabOrder = 1 + object lblCurrentBlockCaption: TLabel + Left = 55 + Top = 7 + Width = 60 + Height = 13 + Alignment = taRightJustify + Caption = 'Total Blocks:' + Color = clBtnFace + ParentColor = False + end + object lblCurrentBlock: TLabel + Left = 121 + Top = 7 + Width = 18 + Height = 13 + Caption = '000' + Color = clBtnFace + ParentColor = False + end + object lblCurrentBlockTimeCaption: TLabel + Left = 25 + Top = 26 + Width = 90 + Height = 13 + Alignment = taRightJustify + Caption = 'Current Block Age:' + Color = clBtnFace + ParentColor = False + end + object lblCurrentBlockTime: TLabel + Left = 121 + Top = 26 + Width = 81 + Height = 13 + Caption = '000 seconds ago' + Color = clBtnFace + ParentColor = False + end + object lblOperationsPendingCaption: TLabel + Left = 17 + Top = 45 + Width = 98 + Height = 13 + Alignment = taRightJustify + Caption = 'Pending Operations:' + Color = clBtnFace + ParentColor = False + end + object lblOperationsPending: TLabel + Left = 121 + Top = 45 + Width = 18 + Height = 13 + Caption = '000' + Color = clBtnFace + ParentColor = False + end + object lblMiningStatusCaption: TLabel + Left = 50 + Top = 64 + Width = 65 + Height = 13 + Alignment = taRightJustify + Caption = 'Miner Clients:' + Color = clBtnFace + ParentColor = False + end + object lblMinersClients: TLabel + Left = 121 + Top = 64 + Width = 18 + Height = 13 + Caption = '000' + Color = clBtnFace + ParentColor = False + end + object lblNodeCaption: TLabel + Left = 52 + Top = 83 + Width = 63 + Height = 13 + Alignment = taRightJustify + Caption = 'Node Status:' + Color = clBtnFace + ParentColor = False + end + object lblNodeStatus: TLabel + Left = 121 + Top = 83 + Width = 15 + Height = 13 + Caption = '???' + Color = clBtnFace + ParentColor = False + end + end + object Panel3: TPanel + Left = 321 + Top = 0 + Width = 240 + Height = 108 + Align = alLeft + BevelKind = bkTile + BevelOuter = bvNone + Caption = ' ' + TabOrder = 2 + object lblTimeAverage: TLabel + Left = 104 + Top = 26 + Width = 18 + Height = 13 + Caption = '000' + Color = clBtnFace + ParentColor = False + end + object lblTimeAverageCaption: TLabel + Left = 29 + Top = 26 + Width = 69 + Height = 13 + Alignment = taRightJustify + Caption = 'Time average:' + Color = clBtnFace + ParentColor = False + end + object lblCurrentAccountsCaption: TLabel + Left = 50 + Top = 7 + Width = 48 + Height = 13 + Alignment = taRightJustify + Caption = 'Accounts:' + Color = clBtnFace + ParentColor = False + end + object lblCurrentAccounts: TLabel + Left = 104 + Top = 7 + Width = 18 + Height = 13 + Caption = '000' + Color = clBtnFace + ParentColor = False + end + object lblTimeAverageAux: TLabel + Left = 104 + Top = 45 + Width = 18 + Height = 13 + Caption = '000' + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clGray + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + ParentColor = False + ParentFont = False + end + object lblBlocksFoundCaption: TLabel + Left = 22 + Top = 64 + Width = 76 + Height = 13 + Alignment = taRightJustify + Caption = 'Blocks Found:' + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [fsBold] + ParentColor = False + ParentFont = False + end + object lblBlocksFound: TLabel + Left = 104 + Top = 64 + Width = 21 + Height = 13 + Hint = 'Blocks found while Miner is running...' + Caption = '000' + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [fsBold] + ParentColor = False + ParentFont = False + ParentShowHint = False + ShowHint = True + end + object lblCurrentDifficultyCaption: TLabel + Left = 22 + Top = 83 + Width = 76 + Height = 13 + Alignment = taRightJustify + Caption = 'Current Target:' + Color = clBtnFace + ParentColor = False + end + object lblCurrentDifficulty: TLabel + Left = 104 + Top = 83 + Width = 18 + Height = 13 + Caption = '000' + Color = clBtnFace + ParentColor = False + end + end + object Panel4: TPanel + Left = 564 + Top = 0 + Width = 360 + Height = 108 + Align = alClient + BevelKind = bkTile + BevelOuter = bvNone + Caption = ' ' + TabOrder = 3 + object lblReceivedMessages: TLabel + Left = 6 + Top = 36 + Width = 184 + Height = 23 + Cursor = crHandPoint + Caption = 'Received Messages' + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clRed + Font.Height = -19 + Font.Name = 'Tahoma' + Font.Style = [fsBold] + ParentColor = False + ParentFont = False + end + object lblBuild: TLabel + Left = 6 + Top = 7 + Width = 49 + Height = 23 + Caption = 'Build' + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -19 + Font.Name = 'Tahoma' + Font.Style = [fsBold] + ParentColor = False + ParentFont = False + end + end +end diff --git a/src/gui-classic/Frames/UFrameInfo.pas b/src/gui-classic/Frames/UFrameInfo.pas new file mode 100644 index 000000000..2b6a15180 --- /dev/null +++ b/src/gui-classic/Frames/UFrameInfo.pas @@ -0,0 +1,192 @@ +unit UFrameInfo; + +interface + +uses + Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, + Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, + Vcl.Imaging.pngimage, Vcl.ExtCtrls; + +type + TFrameInfo = class(TFrame) + Panel1: TPanel; + Image1: TImage; + Splitter1: TSplitter; + Panel2: TPanel; + lblCurrentBlockCaption: TLabel; + lblCurrentBlock: TLabel; + lblCurrentBlockTimeCaption: TLabel; + lblCurrentBlockTime: TLabel; + lblOperationsPendingCaption: TLabel; + lblOperationsPending: TLabel; + lblMiningStatusCaption: TLabel; + lblMinersClients: TLabel; + lblNodeCaption: TLabel; + lblNodeStatus: TLabel; + Splitter2: TSplitter; + Panel3: TPanel; + lblTimeAverage: TLabel; + lblTimeAverageCaption: TLabel; + lblCurrentAccountsCaption: TLabel; + lblCurrentAccounts: TLabel; + lblTimeAverageAux: TLabel; + lblBlocksFoundCaption: TLabel; + lblBlocksFound: TLabel; + lblCurrentDifficultyCaption: TLabel; + lblCurrentDifficulty: TLabel; + Splitter3: TSplitter; + Panel4: TPanel; + lblReceivedMessages: TLabel; + lblBuild: TLabel; + + private + { Private declarations } + FMinersBlocksFound: Integer; + + procedure SetMinersBlocksFound(const Value: Integer); + + public + { Public declarations } + + procedure UpdateNodeStatus; + procedure UpdateBlockChainState; + + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + + property MinersBlocksFound : Integer read FMinersBlocksFound write SetMinersBlocksFound; + end; + +implementation + +{$R *.dfm} + +uses + UFRMWallet, UNetProtocol, UBlockChain, UTime, UConst; + +constructor TFrameInfo.Create(AOwner: TComponent); +begin + inherited Create( AOwner ); + + MinersBlocksFound := 0; + +end; + +destructor TFrameInfo.Destroy; +begin + + inherited Destroy; +end; + +procedure TFrameInfo.SetMinersBlocksFound(const Value: Integer); +begin + FMinersBlocksFound := Value; + lblBlocksFound.Caption := Inttostr(Value); + if Value>0 then lblBlocksFound.Font.Color := clGreen + else lblBlocksFound.Font.Color := clDkGray; +end; + + +procedure TFrameInfo.UpdateNodeStatus; +Var status : String; +begin + If Not Assigned(FRMWallet.Node) then begin + lblNodeStatus.Font.Color := clRed; + lblNodeStatus.Caption := 'Initializing...'; + end else begin + If FRMWallet.Node.IsReady(status) then begin + if TNetData.NetData.NetStatistics.ActiveConnections>0 then begin + lblNodeStatus.Font.Color := clGreen; + if TNetData.NetData.IsDiscoveringServers then begin + lblNodeStatus.Caption := 'Discovering servers'; + end else if TNetData.NetData.IsGettingNewBlockChainFromClient(status) then begin + lblNodeStatus.Caption := 'Obtaining new blockchain '+status; + end else begin + lblNodeStatus.Caption := 'Running'; + end; + end else begin + lblNodeStatus.Font.Color := clRed; + lblNodeStatus.Caption := 'Alone in the world...'; + end; + end else begin + lblNodeStatus.Font.Color := clRed; + lblNodeStatus.Caption := status; + end; + end; + + If Assigned(FRMWallet.BackgroundLabel) then begin + FRMWallet.BackgroundLabel.Font.Color:= lblNodeStatus.Font.Color; + FRMWallet.BackgroundLabel.Caption:='Please wait until finished: '+lblNodeStatus.Caption; + end; +end; + +procedure TFrameInfo.UpdateBlockChainState; +Var isMining : boolean; + i,mc : Integer; + s : String; + f, favg : real; + LLockedMempool : TPCOperationsComp; +begin + UpdateNodeStatus; + mc := 0; + if Assigned(FRMWallet.Node) then begin + if FRMWallet.Node.Bank.BlocksCount>0 then begin + lblCurrentBlock.Caption := Inttostr(FRMWallet.Node.Bank.BlocksCount)+' (0..'+Inttostr(FRMWallet.Node.Bank.BlocksCount-1)+')'; ; + end else lblCurrentBlock.Caption := '(none)'; + lblCurrentAccounts.Caption := Inttostr(FRMWallet.Node.Bank.AccountsCount); + lblCurrentBlockTime.Caption := UnixTimeToLocalElapsedTime(FRMWallet.Node.Bank.LastOperationBlock.timestamp); + LLockedMempool := FRMWallet.Node.LockMempoolRead; + try + lblOperationsPending.Caption := Inttostr(LLockedMempool.Count); + lblCurrentDifficulty.Caption := InttoHex(LLockedMempool.OperationBlock.compact_target,8); + finally + FRMWallet.Node.UnlockMempoolRead; + end; + favg := FRMWallet.Node.Bank.GetActualTargetSecondsAverage(CT_CalcNewTargetBlocksAverage); + f := (CT_NewLineSecondsAvg - favg) / CT_NewLineSecondsAvg; + lblTimeAverage.Caption := 'Last '+Inttostr(CT_CalcNewTargetBlocksAverage)+': '+FormatFloat('0.0',favg)+' sec. (Optimal '+Inttostr(CT_NewLineSecondsAvg)+'s) Deviation '+FormatFloat('0.00%',f*100); + if favg>=CT_NewLineSecondsAvg then begin + lblTimeAverage.Font.Color := clNavy; + end else begin + lblTimeAverage.Font.Color := clOlive; + end; + lblTimeAverageAux.Caption := + Format + ( + 'Last %d: %s sec. - %d: %s sec. - %d: %s sec. - %d: %s sec. - %d: %s sec.', + [ + CT_CalcNewTargetBlocksAverage * 2, FormatFloat('0.0', FRMWallet.Node.Bank.GetActualTargetSecondsAverage(CT_CalcNewTargetBlocksAverage * 2)), + ((CT_CalcNewTargetBlocksAverage * 3) DIV 2) ,FormatFloat('0.0',FRMWallet.Node.Bank.GetActualTargetSecondsAverage((CT_CalcNewTargetBlocksAverage * 3) DIV 2)), + ((CT_CalcNewTargetBlocksAverage DIV 4)*3),FormatFloat('0.0',FRMWallet.Node.Bank.GetActualTargetSecondsAverage(((CT_CalcNewTargetBlocksAverage DIV 4)*3))), + CT_CalcNewTargetBlocksAverage DIV 2,FormatFloat('0.0',FRMWallet.Node.Bank.GetActualTargetSecondsAverage(CT_CalcNewTargetBlocksAverage DIV 2)), + CT_CalcNewTargetBlocksAverage DIV 4,FormatFloat('0.0',FRMWallet.Node.Bank.GetActualTargetSecondsAverage(CT_CalcNewTargetBlocksAverage DIV 4)) + ] + ); + end else begin + isMining := false; + + lblCurrentBlock.Caption := ''; + lblCurrentAccounts.Caption := ''; + lblCurrentBlockTime.Caption := ''; + lblOperationsPending.Caption := ''; + lblCurrentDifficulty.Caption := ''; + lblTimeAverage.Caption := ''; + lblTimeAverageAux.Caption := ''; + end; + if (Assigned(FRMWallet.PoolMiningServer)) And (FRMWallet.PoolMiningServer.Active) then begin + If FRMWallet.PoolMiningServer.ClientsCount>0 then begin + lblMinersClients.Caption := IntToStr(FRMWallet.PoolMiningServer.ClientsCount)+' connected JSON-RPC clients'; + lblMinersClients.Font.Color := clNavy; + end else begin + lblMinersClients.Caption := 'No JSON-RPC clients'; + lblMinersClients.Font.Color := clDkGray; + end; + MinersBlocksFound := FRMWallet.PoolMiningServer.ClientsWins; + end else begin + MinersBlocksFound := 0; + lblMinersClients.Caption := 'JSON-RPC server not active'; + lblMinersClients.Font.Color := clRed; + end; +end; + +end. diff --git a/src/gui-classic/Frames/UFrameLogs.dfm b/src/gui-classic/Frames/UFrameLogs.dfm new file mode 100644 index 000000000..4a77d0f88 --- /dev/null +++ b/src/gui-classic/Frames/UFrameLogs.dfm @@ -0,0 +1,47 @@ +object FrameLogs: TFrameLogs + Left = 0 + Top = 0 + Width = 821 + Height = 531 + TabOrder = 0 + object memoLogs: TMemo + Left = 0 + Top = 33 + Width = 821 + Height = 498 + Align = alClient + ScrollBars = ssBoth + TabOrder = 0 + WordWrap = False + end + object pnlTopLogs: TPanel + Left = 0 + Top = 0 + Width = 821 + Height = 33 + Align = alTop + BevelOuter = bvNone + TabOrder = 1 + DesignSize = ( + 821 + 33) + object cbShowDebugLogs: TCheckBox + Left = 13 + Top = 7 + Width = 102 + Height = 19 + Caption = 'Show Debug Logs' + TabOrder = 0 + end + object ButtonCopyLogToClipboard: TButton + Left = 680 + Top = 4 + Width = 133 + Height = 25 + Anchors = [akTop, akRight] + Caption = 'Copy log to clipboard' + TabOrder = 1 + OnClick = ButtonCopyLogToClipboardClick + end + end +end diff --git a/src/gui-classic/Frames/UFrameLogs.pas b/src/gui-classic/Frames/UFrameLogs.pas new file mode 100644 index 000000000..7df3d2c2f --- /dev/null +++ b/src/gui-classic/Frames/UFrameLogs.pas @@ -0,0 +1,82 @@ +unit UFrameLogs; + +interface + +uses + Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, + Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls, + ULog, UConst; + +type + TFrameLogs = class(TFrame) + memoLogs: TMemo; + pnlTopLogs: TPanel; + cbShowDebugLogs: TCheckBox; + ButtonCopyLogToClipboard: TButton; + procedure ButtonCopyLogToClipboardClick(Sender: TObject); + private + { Private declarations } + public + { Public declarations } + + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + + procedure OnNewLog + ( + logtype : TLogType; + Time : TDateTime; + ThreadID : TThreadID; // carefull, two different types exist one in UConst.Pas and one in System.pas (in Delphi). + const sender, logtext : string + ); + + end; + +implementation + +{$R *.dfm} + +constructor TFrameLogs.Create(AOwner: TComponent); +begin + inherited Create( AOwner ); + +end; + +destructor TFrameLogs.Destroy; +begin + + inherited Destroy; +end; + +procedure TFrameLogs.ButtonCopyLogToClipboardClick(Sender: TObject); +begin + memoLogs.SelectAll; + memoLogs.CopyToClipboard; +end; + +procedure TFrameLogs.OnNewLog +( + logtype: TLogType; + Time : TDateTime; + ThreadID : TThreadID; + const sender,logtext: String +); +Var s : AnsiString; +begin + if (logtype=ltdebug) And (Not cbShowDebugLogs.Checked) then exit; + if ThreadID=MainThreadID then s := ' MAIN:' else s:=' TID:'; + if MemoLogs.Lines.Count>300 then begin + // Limit max lines in logs... + memoLogs.Lines.BeginUpdate; + try + while memoLogs.Lines.Count>250 do memoLogs.Lines.Delete(0); + finally + memoLogs.Lines.EndUpdate; + end; + end; + memoLogs.Lines.Add(formatDateTime('dd/mm/yyyy hh:nn:ss.zzz',Time)+s+IntToHex(PtrInt(ThreadID),8)+' ['+CT_LogType[Logtype]+'] <'+sender+'> '+logtext); + // +end; + + +end. diff --git a/src/gui-classic/Frames/UFrameMessages.dfm b/src/gui-classic/Frames/UFrameMessages.dfm new file mode 100644 index 000000000..4c5a3e5a2 --- /dev/null +++ b/src/gui-classic/Frames/UFrameMessages.dfm @@ -0,0 +1,175 @@ +object FrameMessages: TFrameMessages + Left = 0 + Top = 0 + Width = 764 + Height = 466 + TabOrder = 0 + object Splitter1: TSplitter + Left = 0 + Top = 213 + Width = 764 + Height = 3 + Cursor = crVSplit + Align = alBottom + ResizeStyle = rsUpdate + ExplicitTop = 0 + ExplicitWidth = 304 + end + object PanelBottom: TPanel + Left = 0 + Top = 216 + Width = 764 + Height = 250 + Align = alBottom + Anchors = [akLeft, akTop, akRight] + BevelOuter = bvNone + Caption = ' ' + TabOrder = 0 + object Panel1: TPanel + Left = 0 + Top = 0 + Width = 764 + Height = 20 + Align = alTop + Caption = 'Messages:' + TabOrder = 0 + end + object memoMessages: TMemo + Left = 0 + Top = 20 + Width = 764 + Height = 230 + Align = alClient + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -16 + Font.Name = 'Tahoma' + Font.Style = [] + Lines.Strings = ( + 'dsfa '#195#177'ldsaf '#195#177'lk dasf' + 'dsfklda'#195#177'fs '#195#177'l') + ParentFont = False + ReadOnly = True + ScrollBars = ssBoth + TabOrder = 1 + end + end + object PanelTop: TPanel + Left = 0 + Top = 0 + Width = 764 + Height = 213 + Align = alClient + BevelOuter = bvNone + Caption = ' ' + TabOrder = 1 + object Splitter2: TSplitter + Left = 288 + Top = 0 + Height = 213 + ResizeStyle = rsUpdate + ExplicitLeft = 440 + ExplicitTop = 144 + ExplicitHeight = 100 + end + object PanelLeft: TPanel + Left = 0 + Top = 0 + Width = 288 + Height = 213 + Align = alLeft + BevelOuter = bvNone + Caption = ' ' + TabOrder = 0 + object lbNetConnections: TListBox + Left = 0 + Top = 20 + Width = 288 + Height = 193 + Align = alClient + ItemHeight = 13 + MultiSelect = True + ScrollWidth = 273 + TabOrder = 0 + end + object Panel5: TPanel + Left = 0 + Top = 0 + Width = 288 + Height = 20 + Align = alTop + Caption = 'Available Connections:' + TabOrder = 1 + end + end + object PanelRight: TPanel + Left = 291 + Top = 0 + Width = 473 + Height = 213 + Align = alClient + BevelOuter = bvNone + Caption = ' ' + TabOrder = 1 + object memoMessageToSend: TMemo + Left = 0 + Top = 20 + Width = 473 + Height = 127 + Align = alClient + Lines.Strings = ( + 'memoMessageToSend') + TabOrder = 0 + WantReturns = False + end + object Panel6: TPanel + Left = 0 + Top = 0 + Width = 473 + Height = 20 + Align = alTop + Caption = 'Message to send:' + TabOrder = 1 + end + object Panel7: TPanel + Left = 0 + Top = 147 + Width = 473 + Height = 66 + Align = alBottom + Caption = ' ' + TabOrder = 2 + DesignSize = ( + 473 + 66) + object Label14: TLabel + Left = 14 + Top = 11 + Width = 361 + Height = 13 + Caption = + '(Messages will be encrypted, so only dest connection will be abl' + + 'e to read it)' + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clGrayText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + ParentColor = False + ParentFont = False + end + object bbSendAMessage: TButton + Left = 14 + Top = 30 + Width = 450 + Height = 25 + Anchors = [akLeft, akTop, akRight] + Caption = 'Send a Message' + TabOrder = 0 + OnClick = bbSendAMessageClick + end + end + end + end +end diff --git a/src/gui-classic/Frames/UFrameMessages.pas b/src/gui-classic/Frames/UFrameMessages.pas new file mode 100644 index 000000000..7615e85bd --- /dev/null +++ b/src/gui-classic/Frames/UFrameMessages.pas @@ -0,0 +1,184 @@ +unit UFrameMessages; + +interface + +uses + Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, + Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls, + UNetProtocol; + +type + TFrameMessages = class(TFrame) + PanelBottom: TPanel; + Splitter1: TSplitter; + PanelTop: TPanel; + PanelLeft: TPanel; + Splitter2: TSplitter; + PanelRight: TPanel; + memoMessageToSend: TMemo; + lbNetConnections: TListBox; + Panel5: TPanel; + Panel6: TPanel; + Panel7: TPanel; + Label14: TLabel; + bbSendAMessage: TButton; + Panel1: TPanel; + memoMessages: TMemo; + procedure bbSendAMessageClick(Sender: TObject); + private + { Private declarations } + FMessagesUnreadCount : Integer; + + public + { Public declarations } + + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + + procedure UpdateAvailableConnections; + + procedure OnNodeMessageEvent(NetConnection : TNetConnection; MessageData : String); + + property MessagesUnreadCount : integer read FMessagesUnreadCount write FMessagesUnreadCount; + end; + +implementation + +{$R *.dfm} + +uses + UFRMWallet, USettings, UCrypto, + {$IFNDEF FPC} + System.Generics.Collections + {$ELSE} + Generics.Collections + {$ENDIF}; + +constructor TFrameMessages.Create(AOwner: TComponent); +begin + inherited Create( AOwner ); + + memoMessages.Lines.Clear; + memoMessageToSend.Lines.Clear; + + FMessagesUnreadCount := 0; +end; + +destructor TFrameMessages.Destroy; +begin + + + inherited Destroy; +end; + +procedure TFrameMessages.bbSendAMessageClick(Sender: TObject); +Var basem,m : String; + them, errors : String; + i,n : Integer; + nc : TNetConnection; +begin + FRMWallet.CheckIsReady; + if (lbNetConnections.SelCount<=0) Or (lbNetConnections.ItemIndex<0) then raise Exception.Create('Select at least one connection'); + if lbNetConnections.SelCount<=0 then n := 1 + else n := lbNetConnections.SelCount; + + basem := memoMessageToSend.Lines.Text; + m := ''; + // Clear non valid characters: + for i := Low(basem) to High(basem) do begin + if basem[i] in [#32..#127] then m := m + basem[i] + else m:=m+'.'; + end; + + if trim(m)='' then raise Exception.Create('No message'); + + if Application.MessageBox(PChaR('Send this message to '+inttostr(n)+' nodes?'+#10+ + 'NOTE: Sending unauthorized messages will be considered spam and you will be banned'+#10+ + #10+ + 'Message: '+#10+ + m),PChar(Application.Title),MB_ICONQUESTION+MB_YESNO+MB_DEFBUTTON1)<>IdYes then exit; + them := m; + if n>1 then begin + for i := 0 to lbNetConnections.Items.Count - 1 do begin + if lbNetConnections.Selected[i] then begin + nc := TNetConnection(lbNetconnections.Items.Objects[i]); + if TNetData.NetData.ConnectionExistsAndActive(nc) then begin + FRMWallet.Node.SendNodeMessage(nc,m,errors); + memoMessages.Lines.Add(DateTimeToStr(now)+' Sent to '+nc.ClientRemoteAddr+' > '+m); + end; + end; + end; + end else begin + nc := TNetConnection(lbNetconnections.Items.Objects[lbNetconnections.ItemIndex]); + if TNetData.NetData.ConnectionExistsAndActive(nc) then begin + FRMWallet.Node.SendNodeMessage(nc,m,errors); + memoMessages.Lines.Add(DateTimeToStr(now)+' Sent to '+nc.ClientRemoteAddr+' > '+m); + end; + end; + + Application.MessageBox(PChaR('Message sent to '+inttostr(n)+' nodes'+#10+ + 'Message: '+#10+m),PChar(Application.Title),MB_ICONINFORMATION+MB_OK); +end; + +procedure TFrameMessages.OnNodeMessageEvent(NetConnection: TNetConnection; MessageData: String); +Var s : String; +begin + inc(FMessagesUnreadCount); + if Assigned(NetConnection) then begin + s := DateTimeToStr(now)+' Message received from '+NetConnection.ClientRemoteAddr; + memoMessages.Lines.Add(DateTimeToStr(now)+' Message received from '+NetConnection.ClientRemoteAddr+' Length '+inttostr(Length(MessageData))+' bytes'); + memoMessages.Lines.Add('RECEIVED> '+MessageData); + if TSettings.ShowModalMessages then begin + s := DateTimeToStr(now)+' Message from '+NetConnection.ClientRemoteAddr+#10+ + 'Length '+inttostr(length(MessageData))+' bytes'+#10+#10; + if TCrypto.IsHumanReadable(TEncoding.ANSI.GetBytes(MessageData)) then begin + s := s + MessageData; + end else begin + s := s +'Value in hexadecimal:'+#10+ + TCrypto.ToHexaString(TEncoding.ANSI.GetBytes(MessageData)); + end; + Application.MessageBox(PChar(s),PChar(Application.Title),MB_ICONINFORMATION+MB_OK); + end; + end else begin + memoMessages.Lines.Add(DateTimeToStr(now)+' Internal message: '+MessageData); + end; + if FMessagesUnreadCount>1 then + FRMWallet.FrameInfo.lblReceivedMessages.Caption := Format('You have received %d messages',[FMessagesUnreadCount]) + else + FRMWallet.FrameInfo.lblReceivedMessages.Caption := 'You have received 1 message'; + FRMWallet.FrameInfo.lblReceivedMessages.Visible := true; +end; + +procedure TFrameMessages.UpdateAvailableConnections; +Var i : integer; + NC : TNetConnection; + l : TList; +begin + if Not TNetData.NetData.NetConnections.TryLockList(100,l) then exit; + try + lbNetConnections.Items.BeginUpdate; + Try + lbNetConnections.Items.Clear; + for i := 0 to l.Count - 1 do begin + NC := l[i]; + if NC.Connected then begin + if NC is TNetServerClient then begin + if Not NC.IsMyselfServer then begin + lbNetConnections.Items.AddObject(Format('Client: IP:%s',[NC.ClientRemoteAddr]),NC); + end; + end else begin + if Not NC.IsMyselfServer then begin + lbNetConnections.Items.AddObject(Format('Server: IP:%s',[NC.ClientRemoteAddr]),NC); + end; + end; + end; + end; + Finally + lbNetConnections.Items.EndUpdate; + End; + finally + TNetData.NetData.NetConnections.UnlockList; + end; +end; + +end. diff --git a/src/gui-classic/Frames/UFrameNodeStats.dfm b/src/gui-classic/Frames/UFrameNodeStats.dfm new file mode 100644 index 000000000..85f6493fa --- /dev/null +++ b/src/gui-classic/Frames/UFrameNodeStats.dfm @@ -0,0 +1,121 @@ +object FrameNodeStats: TFrameNodeStats + Left = 0 + Top = 0 + Width = 711 + Height = 458 + TabOrder = 0 + object Splitter1: TSplitter + Left = 0 + Top = 153 + Width = 711 + Height = 3 + Cursor = crVSplit + Align = alTop + ResizeStyle = rsUpdate + ExplicitTop = 233 + ExplicitWidth = 399 + end + object Splitter2: TSplitter + Left = 0 + Top = 301 + Width = 711 + Height = 3 + Cursor = crVSplit + Align = alBottom + ResizeStyle = rsUpdate + ExplicitLeft = 3 + ExplicitTop = 482 + ExplicitWidth = 909 + end + object PanelTop: TPanel + Left = 0 + Top = 0 + Width = 711 + Height = 153 + Align = alTop + BevelOuter = bvNone + Caption = ' ' + TabOrder = 0 + object Panel4: TPanel + Left = 0 + Top = 0 + Width = 711 + Height = 20 + Align = alTop + Caption = 'Active Connections:' + TabOrder = 0 + end + object memoNetConnections: TMemo + Left = 0 + Top = 20 + Width = 711 + Height = 133 + Align = alClient + ReadOnly = True + ScrollBars = ssVertical + TabOrder = 1 + WordWrap = False + end + end + object PanelMiddle: TPanel + Left = 0 + Top = 156 + Width = 711 + Height = 145 + Align = alClient + BevelOuter = bvNone + Caption = ' ' + TabOrder = 1 + object Panel1: TPanel + Left = 0 + Top = 0 + Width = 711 + Height = 20 + Align = alTop + Caption = 'Blacklisted Nodes:' + TabOrder = 0 + end + object memoNetBlackLists: TMemo + Left = 0 + Top = 20 + Width = 711 + Height = 125 + Align = alClient + ReadOnly = True + ScrollBars = ssVertical + TabOrder = 1 + WordWrap = False + end + end + object PanelBottom: TPanel + Left = 0 + Top = 304 + Width = 711 + Height = 154 + Align = alBottom + Anchors = [akLeft, akTop, akRight] + BevelOuter = bvNone + Caption = ' ' + TabOrder = 2 + object Panel2: TPanel + Left = 0 + Top = 0 + Width = 711 + Height = 20 + Align = alTop + Caption = 'Known Node Servers:' + TabOrder = 0 + end + object memoNetServers: TMemo + Left = 0 + Top = 20 + Width = 711 + Height = 134 + Align = alClient + ReadOnly = True + ScrollBars = ssVertical + TabOrder = 1 + WordWrap = False + end + end +end diff --git a/src/gui-classic/Frames/UFrameNodeStats.pas b/src/gui-classic/Frames/UFrameNodeStats.pas new file mode 100644 index 000000000..fbb44231d --- /dev/null +++ b/src/gui-classic/Frames/UFrameNodeStats.pas @@ -0,0 +1,265 @@ +unit UFrameNodeStats; + +interface + +uses + Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, + Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls, + UFRMWalletUserMessages; + +type + TFrameNodeStats = class(TFrame) + PanelTop: TPanel; + Splitter1: TSplitter; + PanelMiddle: TPanel; + PanelBottom: TPanel; + Splitter2: TSplitter; + Panel4: TPanel; + memoNetConnections: TMemo; + Panel1: TPanel; + memoNetBlackLists: TMemo; + Panel2: TPanel; + memoNetServers: TMemo; + private + { Private declarations } + + FMustProcessNetConnectionUpdated : Boolean; + + procedure CM_NetConnectionUpdated(var Msg: TMessage); message CM_PC_NetConnectionUpdated; + + + public + { Public declarations } + + procedure OnNetConnectionsUpdated(Sender : TObject); + procedure OnNetBlackListUpdated(Sender : TObject); + procedure OnNetNodeServersUpdated(Sender: TObject); + + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + end; + +implementation + +{$R *.dfm} + +uses + UNetProtocol, + Utime, + UConst, + {$IFNDEF FPC} + System.Generics.Collections + {$ELSE} + Generics.Collections + {$ENDIF}; + +constructor TFrameNodeStats.Create(AOwner: TComponent); +begin + inherited Create( AOwner ); + + memoNetConnections.Lines.Clear; + memoNetServers.Lines.Clear; + memoNetBlackLists.Lines.Clear; + + FMustProcessNetConnectionUpdated := false; + + // Skybuck: + // unsafe, must be called by FRMWallet first, otherwise UCrypto not initialised. + // or initialize UCrypto before FRMWallet is create. +{ + TNetData.NetData.OnNetConnectionsUpdated := OnNetConnectionsUpdated; + TNetData.NetData.OnBlackListUpdated := OnNetBlackListUpdated; + TNetData.NetData.OnNodeServersUpdated := OnNetNodeServersUpdated; +} +end; + +destructor TFrameNodeStats.Destroy; +begin + + inherited Destroy; +end; + +procedure TFrameNodeStats.OnNetConnectionsUpdated(Sender: TObject); +begin + if FMustProcessNetConnectionUpdated then exit; + FMustProcessNetConnectionUpdated := true; + PostMessage(Self.Handle,CM_PC_NetConnectionUpdated,0,0); +end; + +procedure TFrameNodeStats.OnNetBlackListUpdated(Sender: TObject); +Const CT_TRUE_FALSE : Array[Boolean] Of AnsiString = ('FALSE','TRUE'); +Var i,j,n : integer; + P : PNodeServerAddress; + l : TList; + strings : TStrings; +begin + l := TNetData.NetData.NodeServersAddresses.LockList; + try + strings := memoNetBlackLists.Lines; + strings.BeginUpdate; + Try + strings.Clear; + strings.Add('BlackList Updated: '+DateTimeToStr(now)+' by TID:'+IntToHex(PtrInt(TThread.CurrentThread.ThreadID),8)); + j := 0; n:=0; + for i := 0 to l.Count - 1 do begin + P := l[i]; + if (P^.is_blacklisted) then begin + inc(n); + if Not P^.its_myself then begin + inc(j); + strings.Add(Format('Blacklist IP:%s:%d LastConnection:%s Reason: %s', + [ + P^.ip,P^.port, + DateTimeToStr(UnivDateTime2LocalDateTime( UnixToUnivDateTime(P^.last_connection))),P^.BlackListText])); + end; + end; + end; + Strings.Add(Format('Total Blacklisted IPs: %d (Total %d)',[j,n])); + Finally + strings.EndUpdate; + End; + finally + TNetData.NetData.NodeServersAddresses.UnlockList; + end; +end; + +procedure TFrameNodeStats.OnNetNodeServersUpdated(Sender: TObject); +Var i : integer; + P : PNodeServerAddress; + l : TList; + strings : TStrings; + s : String; +begin + l := TNetData.NetData.NodeServersAddresses.LockList; + try + strings := memoNetServers.Lines; + strings.BeginUpdate; + Try + strings.Clear; + strings.Add('NodeServers Updated: '+DateTimeToStr(now) +' Count: '+inttostr(l.Count)); + for i := 0 to l.Count - 1 do begin + P := l[i]; + if Not (P^.is_blacklisted) then begin + s := Format('Server IP:%s:%d',[P^.ip,P^.port]); + if (P^.last_connection_by_me>0) then begin + s := s + ' [Server] '; + end; + + if Assigned(P.netConnection) then begin + If P.last_connection>0 then s := s+ ' ** ACTIVE **' + else s := s+' ** TRYING TO CONNECT **'; + end; + if P.its_myself then begin + s := s+' ** NOT VALID ** '+P.BlackListText; + end; + if P.last_connection>0 then begin + s := s + ' Last connection: '+DateTimeToStr(UnivDateTime2LocalDateTime( UnixToUnivDateTime(P^.last_connection))); + end; + if P.last_connection_by_server>0 then begin + s := s + ' Last server connection: '+DateTimeToStr(UnivDateTime2LocalDateTime( UnixToUnivDateTime(P^.last_connection_by_server))); + end; + if (P.last_attempt_to_connect>0) then begin + s := s + ' Last attempt to connect: '+DateTimeToStr(P^.last_attempt_to_connect); + end; + if (P.total_failed_attemps_to_connect>0) then begin + s := s + ' (Attempts: '+inttostr(P^.total_failed_attemps_to_connect)+')'; + end; + + strings.Add(s); + end; + end; + Finally + strings.EndUpdate; + End; + finally + TNetData.NetData.NodeServersAddresses.UnlockList; + end; +end; + + +procedure TFrameNodeStats.CM_NetConnectionUpdated(var Msg: TMessage); +Const CT_BooleanToString : Array[Boolean] of String = ('False','True'); +Var i : integer; + NC : TNetConnection; + l : TList; + sClientApp, sLastConnTime : String; + strings, sNSC, sRS, sDisc : TStrings; + hh,nn,ss,ms : Word; +begin + Try + if Not TNetData.NetData.NetConnections.TryLockList(100,l) then exit; + try + strings := memoNetConnections.Lines; + sNSC := TStringList.Create; + sRS := TStringList.Create; + sDisc := TStringList.Create; + strings.BeginUpdate; + Try + for i := 0 to l.Count - 1 do begin + NC := l[i]; + If NC.Client.BytesReceived>0 then begin + sClientApp := '['+IntToStr(NC.NetProtocolVersion.protocol_version)+'-'+IntToStr(NC.NetProtocolVersion.protocol_available)+'] '+NC.ClientAppVersion; + end else begin + sClientApp := '(no data)'; + end; + + if NC.Connected then begin + if NC.Client.LastCommunicationTime>1000 then begin + DecodeTime(now - NC.Client.LastCommunicationTime,hh,nn,ss,ms); + if (hh=0) and (nn=0) And (ss<10) then begin + sLastConnTime := ' - Last comunication <10 sec.'; + end else begin + sLastConnTime := Format(' - Last comunication %.2dm%.2ds',[(hh*60)+nn,ss]); + end; + end else begin + sLastConnTime := ''; + end; + if NC is TNetServerClient then begin + sNSC.Add(Format('Client: IP:%s Block:%d Sent/Received:%d/%d Bytes - %s - Time offset %d - Active since %s %s', + [NC.ClientRemoteAddr,NC.RemoteOperationBlock.block,NC.Client.BytesSent,NC.Client.BytesReceived,sClientApp,NC.TimestampDiff,DateTimeElapsedTime(NC.CreatedTime),sLastConnTime])); + end else begin + if NC.IsMyselfServer then sNSC.Add(Format('MySelf IP:%s Sent/Received:%d/%d Bytes - %s - Time offset %d - Active since %s %s', + [NC.ClientRemoteAddr,NC.Client.BytesSent,NC.Client.BytesReceived,sClientApp,NC.TimestampDiff,DateTimeElapsedTime(NC.CreatedTime),sLastConnTime])) + else begin + sRS.Add(Format('Remote Server: IP:%s Block:%d Sent/Received:%d/%d Bytes - %s - Time offset %d - Active since %s %s', + [NC.ClientRemoteAddr,NC.RemoteOperationBlock.block,NC.Client.BytesSent,NC.Client.BytesReceived,sClientApp,NC.TimestampDiff,DateTimeElapsedTime(NC.CreatedTime),sLastConnTime])); + end; + end; + end else begin + if NC is TNetServerClient then begin + sDisc.Add(Format('Disconnected client: IP:%s - %s',[NC.ClientRemoteAddr,sClientApp])); + end else if NC.IsMyselfServer then begin + sDisc.Add(Format('Disconnected MySelf IP:%s - %s',[NC.ClientRemoteAddr,sClientApp])); + end else begin + sDisc.Add(Format('Disconnected Remote Server: IP:%s %s - %s',[NC.ClientRemoteAddr,CT_BooleanToString[NC.Connected],sClientApp])); + end; + end; + end; + strings.Clear; + strings.Add(Format('Connections Updated %s Clients:%d Servers:%d (valid servers:%d)',[DateTimeToStr(now),sNSC.Count,sRS.Count,TNetData.NetData.NetStatistics.ServersConnectionsWithResponse])); + strings.AddStrings(sRS); + strings.AddStrings(sNSC); + if sDisc.Count>0 then begin + strings.Add(''); + strings.Add('Disconnected connections: '+Inttostr(sDisc.Count)); + strings.AddStrings(sDisc); + end; + Finally + strings.EndUpdate; + sNSC.Free; + sRS.Free; + sDisc.Free; + End; + //CheckMining; + finally + TNetData.NetData.NetConnections.UnlockList; + end; + Finally + FMustProcessNetConnectionUpdated := false; + End; +end; + + + + +end. diff --git a/src/gui-classic/Frames/UFrameOperationsExplorer.dfm b/src/gui-classic/Frames/UFrameOperationsExplorer.dfm new file mode 100644 index 000000000..cd3558847 --- /dev/null +++ b/src/gui-classic/Frames/UFrameOperationsExplorer.dfm @@ -0,0 +1,51 @@ +object FrameOperationsExplorer: TFrameOperationsExplorer + Left = 0 + Top = 0 + Width = 817 + Height = 441 + TabOrder = 0 + object Panel1: TPanel + Left = 0 + Top = 0 + Width = 817 + Height = 41 + Align = alTop + BevelOuter = bvNone + TabOrder = 0 + object Label2: TLabel + Left = 11 + Top = 10 + Width = 102 + Height = 13 + Caption = 'Filter by blocks range' + Color = clBtnFace + ParentColor = False + end + object ebFilterOperationsStartBlock: TEdit + Left = 125 + Top = 7 + Width = 57 + Height = 21 + TabOrder = 0 + OnExit = ebFilterOperationsStartBlockExit + OnKeyPress = ebFilterOperationsStartBlockKeyPress + end + object ebFilterOperationsEndBlock: TEdit + Left = 185 + Top = 7 + Width = 57 + Height = 21 + TabOrder = 1 + OnExit = ebFilterOperationsEndBlockExit + OnKeyPress = ebFilterOperationsEndBlockKeyPress + end + end + object dgOperationsExplorer: TDrawGrid + Left = 0 + Top = 41 + Width = 817 + Height = 400 + Align = alClient + TabOrder = 1 + end +end diff --git a/src/gui-classic/Frames/UFrameOperationsExplorer.pas b/src/gui-classic/Frames/UFrameOperationsExplorer.pas new file mode 100644 index 000000000..4d4d31af1 --- /dev/null +++ b/src/gui-classic/Frames/UFrameOperationsExplorer.pas @@ -0,0 +1,105 @@ +unit UFrameOperationsExplorer; + +interface + +uses + Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, + Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Grids, Vcl.StdCtrls, + Vcl.ExtCtrls; + +type + TFrameOperationsExplorer = class(TFrame) + Panel1: TPanel; + Label2: TLabel; + ebFilterOperationsStartBlock: TEdit; + ebFilterOperationsEndBlock: TEdit; + dgOperationsExplorer: TDrawGrid; + procedure ebFilterOperationsStartBlockExit(Sender: TObject); + procedure ebFilterOperationsEndBlockExit(Sender: TObject); + procedure ebFilterOperationsStartBlockKeyPress(Sender: TObject; + var Key: Char); + procedure ebFilterOperationsEndBlockKeyPress(Sender: TObject; + var Key: Char); + + // shared: + procedure ebFilterOperationsAccountExit(Sender: TObject); + procedure ebFilterOperationsAccountKeyPress(Sender: TObject; var Key: Char); + + private + { Private declarations } + public + { Public declarations } + + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + end; + +implementation + +{$R *.dfm} + +uses + UFRMWallet; + +constructor TFrameOperationsExplorer.Create(AOwner: TComponent); +begin + inherited Create( AOwner ); + + ebFilterOperationsStartBlock.Text := ''; + ebFilterOperationsEndBlock.Text := ''; +end; + +destructor TFrameOperationsExplorer.Destroy; +begin + + inherited Destroy; +end; + +procedure TFrameOperationsExplorer.ebFilterOperationsAccountExit(Sender: TObject); +Var bstart,bend : Int64; +begin + If FRMWallet.Updating then exit; + FRMWallet.Updating := True; + Try + bstart := StrToInt64Def(ebFilterOperationsStartBlock.Text,-1); + if bstart>=0 then ebFilterOperationsStartBlock.Text := Inttostr(bstart) else ebFilterOperationsStartBlock.Text := ''; + bend := StrToInt64Def(ebFilterOperationsEndBlock.Text,-1); + if bend>=0 then ebFilterOperationsEndBlock.Text := Inttostr(bend) else ebFilterOperationsEndBlock.Text := ''; + FRMWallet.OperationsExplorerGrid.SetBlocks(bstart,bend); + Finally + FRMWallet.Updating := false; + End; +end; + +procedure TFrameOperationsExplorer.ebFilterOperationsAccountKeyPress(Sender: TObject; + var Key: Char); +begin + if key=#13 then ebFilterOperationsAccountExit(Nil); +end; + +procedure TFrameOperationsExplorer.ebFilterOperationsStartBlockExit( + Sender: TObject); +begin + ebFilterOperationsAccountExit( Sender ); +end; + +procedure TFrameOperationsExplorer.ebFilterOperationsEndBlockExit( + Sender: TObject); +begin + ebFilterOperationsAccountExit( Sender ); +end; + +procedure TFrameOperationsExplorer.ebFilterOperationsStartBlockKeyPress( + Sender: TObject; var Key: Char); +begin + ebFilterOperationsAccountKeyPress( Sender, Key ); +end; + +procedure TFrameOperationsExplorer.ebFilterOperationsEndBlockKeyPress( + Sender: TObject; var Key: Char); +begin + ebFilterOperationsAccountKeyPress( Sender, Key ); +end; + + +end. diff --git a/src/gui-classic/Frames/UFramePendingOperations.dfm b/src/gui-classic/Frames/UFramePendingOperations.dfm new file mode 100644 index 000000000..80ad758fe --- /dev/null +++ b/src/gui-classic/Frames/UFramePendingOperations.dfm @@ -0,0 +1,55 @@ +object FramePendingOperations: TFramePendingOperations + Left = 0 + Top = 0 + Width = 826 + Height = 522 + TabOrder = 0 + object dgPendingOperations: TDrawGrid + Left = 0 + Top = 86 + Width = 826 + Height = 436 + Align = alClient + TabOrder = 0 + ExplicitLeft = -537 + ExplicitTop = -112 + ExplicitWidth = 857 + ExplicitHeight = 352 + end + object pnlPendingOperations: TPanel + Left = 0 + Top = 0 + Width = 826 + Height = 86 + Align = alTop + BevelOuter = bvNone + BorderWidth = 10 + TabOrder = 1 + ExplicitLeft = -537 + ExplicitWidth = 857 + object Label10: TLabel + Left = 10 + Top = 10 + Width = 806 + Height = 66 + Align = alClient + AutoSize = False + Caption = + 'Here you can see Operations transmited/received from other nodes' + + ' that will be included in next block. There is no guarantee that' + + ' other nodes will include them when mining, so it'#39's important th' + + 'at you mine too to help include Operations to the main BlockChai' + + 'n' + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -16 + Font.Name = 'Tahoma' + Font.Style = [] + ParentColor = False + ParentFont = False + WordWrap = True + ExplicitWidth = 837 + end + end +end diff --git a/src/gui-classic/Frames/UFramePendingOperations.pas b/src/gui-classic/Frames/UFramePendingOperations.pas new file mode 100644 index 000000000..ba1ac7ace --- /dev/null +++ b/src/gui-classic/Frames/UFramePendingOperations.pas @@ -0,0 +1,40 @@ +unit UFramePendingOperations; + +interface + +uses + Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, + Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, + Vcl.ExtCtrls, Vcl.Grids; + +type + TFramePendingOperations = class(TFrame) + dgPendingOperations: TDrawGrid; + pnlPendingOperations: TPanel; + Label10: TLabel; + private + { Private declarations } + public + { Public declarations } + + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + end; + +implementation + +{$R *.dfm} + +constructor TFramePendingOperations.Create(AOwner: TComponent); +begin + inherited Create( AOwner ); + +end; + +destructor TFramePendingOperations.Destroy; +begin + + inherited Destroy; +end; + +end. diff --git a/src/gui-classic/UFRMAbout.pas b/src/gui-classic/UFRMAbout.pas index 9ce98a7a5..a29979bdf 100644 --- a/src/gui-classic/UFRMAbout.pas +++ b/src/gui-classic/UFRMAbout.pas @@ -52,6 +52,9 @@ TFRMAbout = class(TForm) procedure Label4Click(Sender: TObject); procedure Label5Click(Sender: TObject); private + function GetBuildString : string; + function GetProtocolVersionString : string; + { Private declarations } Procedure OpenURL(Url : String); public @@ -80,13 +83,47 @@ implementation {$R *.lfm} {$ENDIF} +function TFRMAbout.GetBuildString : string; +begin + result := + 'Build: ' + CT_ClientAppVersion + + ' OpenSSL: ' + + {$IFDEF Use_OpenSSL} + IntToHex(OpenSSLVersion,8) + {$ELSE} + 'NONE' + {$ENDIF} + + ' Compiler: ' + {$IFDEF FPC} + + 'FPC' + {$IFDEF CPU32}+' 32b'{$ELSE}+' 64b'{$ENDIF} + {$ELSE}+ + 'Delphi' + {$IFDEF CPU32BITS}+' 32b'{$ELSE}+' 64b'{$ENDIF} + {$ENDIF}; +end; + +function TFRMAbout.GetProtocolVersionString : string; +begin + result := + Format + ( + 'BlockChain Protocol: %d (%d) - Net Protocol: %d (%d)', + [ + TNode.Node.Bank.SafeBox.CurrentProtocol, + CT_BlockChain_Protocol_Available, + CT_NetProtocol_Version, + CT_NetProtocol_Available + ] + ); +end; + procedure TFRMAbout.FormCreate(Sender: TObject); begin {$IFDEF USE_GNUGETTEXT}TranslateComponent(self);{$ENDIF} // - lblBuild.Caption := 'Build: '+CT_ClientAppVersion+' OpenSSL: '+{$IFDEF Use_OpenSSL}IntToHex(OpenSSLVersion,8){$ELSE}'NONE'{$ENDIF}+' Compiler: '{$IFDEF FPC}+'FPC'{$IFDEF CPU32}+' 32b'{$ELSE}+' 64b'{$ENDIF}{$ELSE}+'Delphi'{$IFDEF CPU32BITS}+' 32b'{$ELSE}+' 64b'{$ENDIF}{$ENDIF}; - lblProtocolVersion.Caption := Format('BlockChain Protocol: %d (%d) - Net Protocol: %d (%d)',[TNode.Node.Bank.SafeBox.CurrentProtocol,CT_BlockChain_Protocol_Available, - CT_NetProtocol_Version, CT_NetProtocol_Available]); + lblBuild.Caption := GetBuildString; + lblProtocolVersion.Caption := GetProtocolVersionString; end; procedure TFRMAbout.Label4Click(Sender: TObject); diff --git a/src/gui-classic/UFRMNodesIp.dfm b/src/gui-classic/UFRMNodesIp.dfm index ebc059f6e..708abbbb9 100644 --- a/src/gui-classic/UFRMNodesIp.dfm +++ b/src/gui-classic/UFRMNodesIp.dfm @@ -2,10 +2,9 @@ object FRMNodesIp: TFRMNodesIp Left = 0 Top = 0 BorderIcons = [biSystemMenu] - BorderStyle = bsSingle Caption = 'Nodes IP' - ClientHeight = 367 - ClientWidth = 334 + ClientHeight = 411 + ClientWidth = 389 Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText @@ -17,70 +16,81 @@ object FRMNodesIp: TFRMNodesIp OnCreate = FormCreate PixelsPerInch = 96 TextHeight = 13 - object Label1: TLabel - Left = 30 - Top = 25 - Width = 143 - Height = 13 - Caption = 'Available Nodes Ip to connect' - end object memoNodesIp: TMemo - Left = 30 - Top = 45 - Width = 276 - Height = 226 + Left = 0 + Top = 20 + Width = 389 + Height = 329 + Align = alClient Lines.Strings = ( 'memoNodesIp') ScrollBars = ssBoth TabOrder = 0 + ExplicitTop = 23 + ExplicitHeight = 326 end - object bbOk: TBitBtn - Left = 138 - Top = 317 - Width = 75 - Height = 25 - Caption = 'OK' - Default = True - DoubleBuffered = True - Glyph.Data = { - DE010000424DDE01000000000000760000002800000024000000120000000100 - 0400000000006801000000000000000000001000000000000000000000000000 - 80000080000000808000800000008000800080800000C0C0C000808080000000 - FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF00333333333333 - 3333333333333333333333330000333333333333333333333333F33333333333 - 00003333344333333333333333388F3333333333000033334224333333333333 - 338338F3333333330000333422224333333333333833338F3333333300003342 - 222224333333333383333338F3333333000034222A22224333333338F338F333 - 8F33333300003222A3A2224333333338F3838F338F33333300003A2A333A2224 - 33333338F83338F338F33333000033A33333A222433333338333338F338F3333 - 0000333333333A222433333333333338F338F33300003333333333A222433333 - 333333338F338F33000033333333333A222433333333333338F338F300003333 - 33333333A222433333333333338F338F00003333333333333A22433333333333 - 3338F38F000033333333333333A223333333333333338F830000333333333333 - 333A333333333333333338330000333333333333333333333333333333333333 - 0000} - NumGlyphs = 2 - ParentDoubleBuffered = False + object Panel1: TPanel + Left = 0 + Top = 0 + Width = 389 + Height = 20 + Align = alTop + Caption = 'Available Nodes IP to connect:' TabOrder = 1 - OnClick = bbOkClick end - object bbCancel: TBitBtn - Left = 231 - Top = 317 - Width = 75 - Height = 25 - DoubleBuffered = True - Kind = bkCancel - ParentDoubleBuffered = False + object Panel2: TPanel + Left = 0 + Top = 349 + Width = 389 + Height = 62 + Align = alBottom + Caption = ' ' TabOrder = 2 - end - object cbTryOnlyWithThisServers: TCheckBox - Left = 35 - Top = 285 - Width = 271 - Height = 17 - Caption = 'Try to connect ONLY with this servers' - TabOrder = 3 - OnClick = cbTryOnlyWithThisServersClick + object bbOk: TBitBtn + Left = 9 + Top = 29 + Width = 75 + Height = 25 + Caption = 'OK' + Default = True + Glyph.Data = { + DE010000424DDE01000000000000760000002800000024000000120000000100 + 0400000000006801000000000000000000001000000000000000000000000000 + 80000080000000808000800000008000800080800000C0C0C000808080000000 + FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF00333333333333 + 3333333333333333333333330000333333333333333333333333F33333333333 + 00003333344333333333333333388F3333333333000033334224333333333333 + 338338F3333333330000333422224333333333333833338F3333333300003342 + 222224333333333383333338F3333333000034222A22224333333338F338F333 + 8F33333300003222A3A2224333333338F3838F338F33333300003A2A333A2224 + 33333338F83338F338F33333000033A33333A222433333338333338F338F3333 + 0000333333333A222433333333333338F338F33300003333333333A222433333 + 333333338F338F33000033333333333A222433333333333338F338F300003333 + 33333333A222433333333333338F338F00003333333333333A22433333333333 + 3338F38F000033333333333333A223333333333333338F830000333333333333 + 333A333333333333333338330000333333333333333333333333333333333333 + 0000} + NumGlyphs = 2 + TabOrder = 0 + OnClick = bbOkClick + end + object bbCancel: TBitBtn + Left = 90 + Top = 29 + Width = 75 + Height = 25 + Kind = bkCancel + NumGlyphs = 2 + TabOrder = 1 + end + object cbTryOnlyWithThisServers: TCheckBox + Left = 9 + Top = 7 + Width = 271 + Height = 17 + Caption = 'Try to connect ONLY with this servers' + TabOrder = 2 + OnClick = cbTryOnlyWithThisServersClick + end end end diff --git a/src/gui-classic/UFRMNodesIp.pas b/src/gui-classic/UFRMNodesIp.pas index 1a0da863f..d1d451a3d 100644 --- a/src/gui-classic/UFRMNodesIp.pas +++ b/src/gui-classic/UFRMNodesIp.pas @@ -29,12 +29,13 @@ interface LCLIntf, LCLType, LMessages, {$ENDIF} Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, - Dialogs, StdCtrls, Buttons, UAppParams; + Dialogs, StdCtrls, Buttons, UAppParams, Vcl.ExtCtrls; type TFRMNodesIp = class(TForm) memoNodesIp: TMemo; - Label1: TLabel; + Panel1: TPanel; + Panel2: TPanel; bbOk: TBitBtn; bbCancel: TBitBtn; cbTryOnlyWithThisServers: TCheckBox; diff --git a/src/gui-classic/UFRMPascalCoinWalletConfig.dfm b/src/gui-classic/UFRMPascalCoinWalletConfig.dfm deleted file mode 100644 index a67436c42..000000000 --- a/src/gui-classic/UFRMPascalCoinWalletConfig.dfm +++ /dev/null @@ -1,432 +0,0 @@ -object FRMPascalCoinWalletConfig: TFRMPascalCoinWalletConfig - Left = 462 - Top = 234 - BorderIcons = [biSystemMenu] - BorderStyle = bsSingle - Caption = 'Options' - ClientHeight = 581 - ClientWidth = 374 - Color = clBtnFace - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = -11 - Font.Name = 'Tahoma' - Font.Style = [] - OldCreateOrder = True - Position = poOwnerFormCenter - OnCreate = FormCreate - PixelsPerInch = 96 - TextHeight = 13 - object Label1: TLabel - Left = 30 - Top = 403 - Width = 120 - Height = 13 - Caption = 'Default fee for operation' - Color = clBtnFace - ParentColor = False - end - object Label2: TLabel - Left = 30 - Top = 116 - Width = 98 - Height = 13 - Caption = 'Internet Server Port' - Color = clBtnFace - ParentColor = False - end - object lblDefaultInternetServerPort: TLabel - Left = 248 - Top = 116 - Width = 70 - Height = 13 - Caption = '(Default XXXX)' - Color = clBtnFace - ParentColor = False - end - object Label3: TLabel - Left = 15 - Top = 67 - Width = 60 - Height = 13 - Caption = 'Miner Name:' - Color = clBtnFace - ParentColor = False - end - object Label4: TLabel - Left = 90 - Top = 90 - Width = 259 - Height = 13 - Caption = 'This name will be included in each new block you mine!' - Color = clBtnFace - Font.Charset = ANSI_CHARSET - Font.Color = clGray - Font.Height = -11 - Font.Name = 'Tahoma' - Font.Pitch = fpVariable - Font.Style = [] - Font.Quality = fqDraft - ParentColor = False - ParentFont = False - end - object Label5: TLabel - Left = 30 - Top = 226 - Width = 73 - Height = 13 - Caption = 'JSON-RPC Port' - Color = clBtnFace - ParentColor = False - end - object lblDefaultJSONRPCMinerServerPort: TLabel - Left = 248 - Top = 226 - Width = 70 - Height = 13 - Caption = '(Default XXXX)' - Color = clBtnFace - ParentColor = False - end - object Label6: TLabel - Left = 24 - Top = 162 - Width = 57 - Height = 13 - Caption = 'Allowed IP'#39's' - Color = clBtnFace - ParentColor = False - end - object Label7: TLabel - Left = 90 - Top = 183 - Width = 209 - Height = 13 - Caption = 'Ip'#39's separated by semicolon or empty for all' - Color = clBtnFace - Font.Charset = ANSI_CHARSET - Font.Color = clGray - Font.Height = -11 - Font.Name = 'Tahoma' - Font.Pitch = fpVariable - Font.Style = [] - Font.Quality = fqDraft - ParentColor = False - ParentFont = False - end - object cbJSONRPCMinerServerActive: TCheckBox - Left = 15 - Top = 200 - Width = 225 - Height = 19 - Caption = 'JSON-RPC Server Miner (TCP/IP, no HTTP)' - TabOrder = 6 - end - object ebDefaultFee: TEdit - Left = 170 - Top = 400 - Width = 56 - Height = 21 - Alignment = taRightJustify - TabOrder = 12 - Text = '0' - end - object cbSaveLogFiles: TCheckBox - Left = 15 - Top = 427 - Width = 78 - Height = 19 - Caption = 'Save log file' - TabOrder = 13 - OnClick = cbSaveLogFilesClick - end - object cbShowLogs: TCheckBox - Left = 15 - Top = 465 - Width = 68 - Height = 19 - Caption = 'Show logs' - TabOrder = 15 - end - object bbOk: TBitBtn - Left = 184 - Top = 530 - Width = 75 - Height = 30 - Kind = bkOK - NumGlyphs = 2 - TabOrder = 18 - OnClick = bbOkClick - end - object bbCancel: TBitBtn - Left = 274 - Top = 530 - Width = 75 - Height = 30 - Kind = bkCancel - NumGlyphs = 2 - TabOrder = 19 - end - object udInternetServerPort: TUpDown - Left = 226 - Top = 113 - Width = 16 - Height = 21 - Associate = ebInternetServerPort - Min = 1 - Max = 25000 - Position = 4004 - TabOrder = 3 - Thousands = False - end - object ebInternetServerPort: TEdit - Left = 170 - Top = 113 - Width = 56 - Height = 21 - Alignment = taRightJustify - TabOrder = 2 - Text = '4004' - end - object bbUpdatePassword: TBitBtn - Left = 15 - Top = 14 - Width = 337 - Height = 38 - Caption = 'Wallet Password' - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = -13 - Font.Name = 'Tahoma' - Font.Style = [fsBold] - Glyph.Data = { - 76060000424D7606000000000000360400002800000018000000180000000100 - 0800000000004002000000000000000000000001000000010000000000000101 - 0100020202000303030004040400050505000606060007070700080808000909 - 09000A0A0A000B0B0B000C0C0C000D0D0D000E0E0E000F0F0F00101010001111 - 1100121212001313130014141400151515001616160017171700181818001919 - 19001A1A1A001B1B1B001C1C1C001D1D1D001E1E1E001F1F1F00202020002121 - 2100222222002323230024242400252525002626260027272700282828002929 - 29002A2A2A002B2B2B002C2C2C002D2D2D002E2E2E002F2F2F00303030003131 - 3100323232003333330034343400353535003636360037373700383838003939 - 39003A3A3A003B3B3B003C3C3C003D3D3D003E3E3E003F3F3F00404040004141 - 4100424242004343430044444400454545004646460047474700484848004949 - 49004A4A4A004B4B4B004C4C4C004D4D4D004E4E4E004F4F4F00505050005151 - 5100525252005353530054545400555555005656560057575700585858005959 - 59005A5A5A005B5B5B005C5C5C005D5D5D005E5E5E00685968007C4F7C009441 - 9400B72CB700DD15DD00F506F500FD01FD00FE00FE00FE00FE00FE00FE00FE00 - FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00 - FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00 - FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00 - FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00 - FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00 - FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00 - FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00 - FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00 - FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00 - FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00 - FE00FE00FE00FE00FE00FE00FE00F008F900D517F000BD24E800A830E1007B4B - D0005065C1003774B7002B7DB100237FAC001F82AD001C83AD001785AE001687 - AF001489B100128AB300108CB6000F8EB9000D91BB000C94BF000A97C3000A99 - C5000A9AC7000B9BC8000B9CCA000C9ECC000C9FCD000DA0CE000DA1CE000EA2 - CF0011A3CF0015A4CF0018A5CF001CA7D10021A9D1002AAAD00035AACD0035AD - D00035AFD30035B1D60037B5D8003AB8DB003EB9DC0040BBDD0045BEDE004CC1 - E00055C6E3005BC8E40061CAE40066CBE3006BCCE30072D3E60078D8EB0080D8 - EE0083D9F10085DCF40088DBF5008BDBF6008EDAF70091DAF70095DCF70097E0 - F7009EE3F800A4E7F900A9E9F900AEE9F900B5EBF900B2EBF800919191919191 - 919191919191919191919191919191919191919191919191D5E7E8E7E3DED591 - 919191919191919191919191919191D6DDF7F8F8F7F6F4EEE6D5919191919191 - 919191919191D7DADEF8F8F6F7F6EDF1F8F1E69191919191919191919191DADE - DFFAFAF8F7F7E9EDF7F7F8EB91919191919191919191DDE5E3FCFCFAFAEEE0E9 - F3F7F7F7DC919191919191919191DEE7E4FEFEFCFCEDC5E0EFF7F6F6DC919191 - 919191919191DEEAE7FEFEFEFDFBC4C4F5F7F6F6DC919191919191919191E3EC - E9FEFEFEFEFEE0C3F9F7F6F6DC919191919191919191E3E9E3F8F8F1F1F8FBFB - FCFAF7F6DC919191919191919191DCEAEAE0E1E9E5E3DEE4EBF2FAF9DC919191 - 919191919191DBF3EEC5C5EFF3EBE5DDD9D6E6F5DC91919191919191919191D5 - E8EDF1FAF6F0EAE4DAD1D2DBDC919191919191919191919191DBE8F0F3F3F3E4 - D0CFE4D8DC919191919191919191919191919191D5DEE4DED2CFD4D491919191 - 91919191919191919191919191919191D2CE9191919191919191919191919191 - 91C8C89191919191D2CE919191919191919191919191919191D9D09191919191 - D2CE919191919191919191919191919191E6E39191919191D2CE919191919191 - 919191919191919191E0F3CE91919191D2CE9191919191919191919191919191 - 9191EFF6E1C9C8CDD9CC91919191919191919191919191919191C9EDF9F3F3EB - DC91919191919191919191919191919191919191CBE0E1CF9191919191919191 - 9191919191919191919191919191919191919191919191919191} - ParentFont = False - TabOrder = 0 - OnClick = bbUpdatePasswordClick - end - object ebMinerName: TEdit - Left = 90 - Top = 64 - Width = 261 - Height = 21 - TabOrder = 1 - Text = 'ebMinerName' - end - object cbShowModalMessages: TCheckBox - Left = 170 - Top = 427 - Width = 127 - Height = 19 - Caption = 'Show modal messages' - TabOrder = 16 - end - object udJSONRPCMinerServerPort: TUpDown - Left = 226 - Top = 223 - Width = 16 - Height = 21 - Associate = ebJSONRPCMinerServerPort - Min = 1 - Max = 25000 - Position = 4009 - TabOrder = 8 - Thousands = False - end - object ebJSONRPCMinerServerPort: TEdit - Left = 170 - Top = 223 - Width = 56 - Height = 21 - Alignment = taRightJustify - TabOrder = 7 - Text = '4009' - end - object gbMinerPrivateKey: TGroupBox - Left = 8 - Top = 250 - Width = 334 - Height = 121 - Caption = ' Miner Server Private Key: ' - TabOrder = 9 - object rbGenerateANewPrivateKeyEachBlock: TRadioButton - Left = 18 - Top = 6 - Width = 277 - Height = 19 - Caption = 'Generate a new private key for each generated block' - TabOrder = 0 - end - object rbUseARandomKey: TRadioButton - Left = 18 - Top = 26 - Width = 146 - Height = 19 - Caption = 'Use a random existing key' - TabOrder = 1 - end - object rbMineAllwaysWithThisKey: TRadioButton - Left = 18 - Top = 47 - Width = 146 - Height = 19 - Caption = 'Always mine with this key:' - TabOrder = 2 - end - object cbPrivateKeyToMine: TComboBox - Left = 43 - Top = 71 - Width = 266 - Height = 21 - Style = csDropDownList - TabOrder = 3 - end - end - object cbSaveDebugLogs: TCheckBox - Left = 31 - Top = 445 - Width = 118 - Height = 19 - Caption = 'Save debug logs too' - TabOrder = 14 - end - object bbOpenDataFolder: TBitBtn - Left = 16 - Top = 530 - Width = 131 - Height = 30 - Caption = 'Open Data Folder' - Glyph.Data = { - 36040000424D3604000000000000360000002800000010000000100000000100 - 2000000000000004000064000000640000000000000000000000078DBE4D078D - BEFF078DBEFF078DBEFF078DBEFF078DBEFF078DBEFF078DBEFF078DBEFF078D - BEFF078DBEFF078DBEFF078DBEFF078DBEFFFFFFFF00FFFFFF00078DBEFF25A1 - D1FF70C6E7FF6BCFF9FF66CDF9FF65CDF9FF65CDF9FF65CDF9FF65CDF8FF65CD - F9FF65CDF8FF66CEF9FF39ADD8FF078DBEFF078DBE4DFFFFFF00078DBEFF4CBC - E7FF5EB8DAFF94DFFBFF6FD4FAFF6FD4F9FF6ED4FAFF6FD4F9FF6FD4FAFF6FD4 - FAFF6FD4FAFF6ED4F9FF3EB1D9FF84D7EBFF078DBEFFFFFFFF00078DBEFF72D6 - FAFF1593C2FFB6ECFDFF7DDDFBFF79DCFBFF79DCFBFF79DCFBFF79DCFBFF7ADC - FBFF79DCFAFF79DCFAFF44B5D9FFAEF1F9FF078DBEFFFFFFFF00078DBEFF79DD - FBFF1899C7FF94DDF3FFA2EBFCFF84E4FBFF83E4FCFF83E4FCFF84E4FCFF83E4 - FCFF83E4FBFF84E5FCFF48B9DAFFB3F4F9FF078DBEFF078DBE4D078DBEFF82E3 - FCFF43B7DCFF4BB9DBFFBFF4FDFF8EEBFCFF8DEBFCFF8DEBFDFF8DEBFDFF8DEB - FCFF8DEBFDFF8DEBFCFF4CBBDAFFB6F7F9FF6DCAE0FF078DBEFF078DBEFF8AEA - FCFF77DCF3FF1496C3FFFFFFFFFFC9F8FEFFC9F8FEFFC9F8FEFFC9F8FFFFC9F7 - FFFFC9F8FEFFC9F8FFFF9CD6E7FFDFFAFBFFDBF7FAFF078DBEFF078DBEFF93F0 - FEFF93F0FDFF1697C5FF078DBEFF078DBEFF078DBEFF078DBEFF078DBEFF078D - BEFF078DBEFF078DBEFF078DBEFF078DBEFF078DBEFF078DBEFF078DBEFF9BF5 - FEFF9AF6FEFF9AF6FEFF9BF5FDFF9BF6FEFF9AF6FEFF9BF5FEFF9AF6FDFF9BF5 - FEFF9AF6FEFF9AF6FEFF0989BAFFFFFFFF00FFFFFF00FFFFFF00078DBEFFFEFE - FEFFA0FBFFFFA0FBFEFFA0FBFEFFA1FAFEFFA1FBFEFFA0FAFEFFA1FBFEFFA1FB - FFFFA0FBFFFFA1FBFFFF0989BAFFFFFFFF00FFFFFF00FFFFFF00078DBE4D078D - BEFFFEFEFEFFA5FEFFFFA5FEFFFFA5FEFFFF078DBEFF078DBEFF078DBEFF078D - BEFF078DBEFF078DBEFFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00078D - BE4D078DBEFF078DBEFF078DBEFF078DBEFF078DBE4DFFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00} - TabOrder = 17 - OnClick = bbOpenDataFolderClick - end - object cbJSONRPCPortEnabled: TCheckBox - Left = 15 - Top = 136 - Width = 205 - Height = 19 - Caption = 'JSON-RPC Server port enabled (HTTP)' - TabOrder = 4 - OnClick = cbJSONRPCPortEnabledClick - end - object ebJSONRPCAllowedIPs: TEdit - Left = 90 - Top = 159 - Width = 261 - Height = 21 - TabOrder = 5 - Text = 'ebJSONRPCAllowedIPs' - end - object cbDownloadNewCheckpoint: TCheckBox - Left = 16 - Top = 373 - Width = 271 - Height = 19 - Caption = 'Download new Checkpoint if blockchain older than...' - TabOrder = 10 - OnClick = cbDownloadNewCheckpointClick - end - object ebMinFutureBlocksToDownloadNewSafebox: TEdit - Left = 296 - Top = 373 - Width = 53 - Height = 21 - Alignment = taRightJustify - TabOrder = 11 - Text = '0' - end - object bbChangeLanguage: TBitBtn - Left = 15 - Top = 488 - Width = 131 - Height = 30 - Caption = 'Change UI language' - TabOrder = 20 - OnClick = bbChangeLanguageClick - end -end diff --git a/src/gui-classic/UFRMSelectLanguage.dfm b/src/gui-classic/UFRMSelectLanguage.dfm index 806ecac26..5a536af31 100644 --- a/src/gui-classic/UFRMSelectLanguage.dfm +++ b/src/gui-classic/UFRMSelectLanguage.dfm @@ -1,49 +1,75 @@ object FRMChangeLanguage: TFRMChangeLanguage Left = 2170 - Height = 451 Top = 250 - Width = 374 BorderIcons = [biSystemMenu] BorderStyle = bsSingle Caption = 'Language Selection' ClientHeight = 451 ClientWidth = 374 - OnCreate = FormCreate + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + OldCreateOrder = True Position = poOwnerFormCenter - object bbOk: TBitBtn - Left = 184 - Height = 30 - Top = 400 - Width = 75 - Caption = 'OK' - Kind = bkOK - ModalResult = 1 + OnCreate = FormCreate + PixelsPerInch = 96 + TextHeight = 13 + object lbxAvailableLanguages: TListBox + Left = 0 + Top = 41 + Width = 374 + Height = 357 + Align = alClient + ItemHeight = 13 TabOrder = 0 + ExplicitLeft = 15 + ExplicitTop = 56 + ExplicitWidth = 337 + ExplicitHeight = 328 end - object bbCancel: TBitBtn - Left = 274 - Height = 30 - Top = 400 - Width = 75 - Caption = 'Cancel' - Kind = bkCancel - ModalResult = 2 + object Panel1: TPanel + Left = 0 + Top = 0 + Width = 374 + Height = 41 + Align = alTop + Caption = 'Select your preferred language' TabOrder = 1 + ExplicitLeft = 144 + ExplicitTop = 16 + ExplicitWidth = 185 end - object lbxAvailableLanguages: TListBox - Left = 15 - Height = 328 - Top = 56 - Width = 337 - ItemHeight = 0 + object Panel2: TPanel + Left = 0 + Top = 398 + Width = 374 + Height = 53 + Align = alBottom + Caption = ' ' TabOrder = 2 - end - object Label1: TLabel - Left = 16 - Height = 15 - Top = 24 - Width = 161 - Caption = 'Select your preferred language' - ParentColor = False + ExplicitLeft = 8 + ExplicitTop = 390 + ExplicitWidth = 358 + object bbOk: TBitBtn + Left = 15 + Top = 13 + Width = 75 + Height = 30 + Kind = bkOK + NumGlyphs = 2 + TabOrder = 0 + end + object bbCancel: TBitBtn + Left = 106 + Top = 13 + Width = 75 + Height = 30 + Kind = bkCancel + NumGlyphs = 2 + TabOrder = 1 + end end end diff --git a/src/gui-classic/UFRMSelectLanguage.pas b/src/gui-classic/UFRMSelectLanguage.pas index f7ea809a9..92eebf2fe 100644 --- a/src/gui-classic/UFRMSelectLanguage.pas +++ b/src/gui-classic/UFRMSelectLanguage.pas @@ -7,17 +7,19 @@ interface uses - gnugettext,Classes, SysUtils, Forms, Controls, Graphics, Dialogs, Buttons, StdCtrls; + gnugettext,Classes, SysUtils, Forms, Controls, Graphics, Dialogs, Buttons, StdCtrls, + Vcl.ExtCtrls; type { TFRMChangeLanguage } TFRMChangeLanguage = class(TForm) - bbCancel: TBitBtn; - bbOk: TBitBtn; - Label1: TLabel; lbxAvailableLanguages: TListBox; + Panel1: TPanel; + Panel2: TPanel; + bbOk: TBitBtn; + bbCancel: TBitBtn; procedure FormCreate(Sender: TObject); private public diff --git a/src/gui-classic/UFRMTestWallet.dfm b/src/gui-classic/UFRMTestWallet.dfm new file mode 100644 index 000000000..3dcf30c53 --- /dev/null +++ b/src/gui-classic/UFRMTestWallet.dfm @@ -0,0 +1,5 @@ +inherited FRMTestWallet: TFRMTestWallet + Caption = 'FRMTestWallet' + PixelsPerInch = 96 + TextHeight = 13 +end diff --git a/src/gui-classic/UFRMTestWallet.pas b/src/gui-classic/UFRMTestWallet.pas new file mode 100644 index 000000000..57dff08be --- /dev/null +++ b/src/gui-classic/UFRMTestWallet.pas @@ -0,0 +1,508 @@ +unit UFRMTestWallet; + +interface + +uses + Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, + Vcl.Controls, Vcl.Forms, Vcl.Dialogs, UFRMWallet, Vcl.Menus, Vcl.ExtCtrls, + UFrameMessages, UFrameNodeStats, UFrameLogs, UFrameOperationsExplorer, + UFrameBlockExplorer, UFramePendingOperations, UFrameAccountExplorer, + Vcl.ComCtrls, Vcl.StdCtrls, Vcl.Imaging.pngimage, + {$IFNDEF FPC} + System.Generics.Collections + {$ELSE} + Generics.Collections + {$ENDIF}; + +type + TFRMTestWallet = class(TFRMWallet) + procedure FormCreate(Sender: TObject); + private + procedure Test_ShowDiagnosticTool(Sender: TObject); + + { Private declarations } + Procedure InitMenuForTesting; + {$IFDEF TESTNET} + Procedure Test_RandomOperations(Sender: TObject); + {$IFDEF TESTING_NO_POW_CHECK} + Procedure Test_CreateABlock(Sender: TObject); + {$ENDIF} + Procedure Test_ConnectDisconnect(Sender: TObject); + {$ENDIF} +// Procedure Test_ShowPublicKeys(Sender: TObject); + Procedure Test_ShowOperationsInMemory(Sender: TObject); + Procedure Test_FindAccountsForPrivateBuyOrSwapToMe(Sender : TObject); + + public + { Public declarations } + end; + +var + FRMTestWallet: TFRMTestWallet; + +implementation + +{$IFnDEF FPC} + {$R *.dfm} +{$ELSE} + {$R *.lfm} +{$ENDIF} + +Uses + UFolderHelper, + {$IFDEF USE_GNUGETTEXT}gnugettext,{$ENDIF} + {$IFDEF Use_OpenSSL} + UOpenSSL, + {$ENDIF} + ULog, Grids, UAppParams, UBlockChain, + UNode, UGridUtils, UJSONFunctions, UAccounts, UNetProtocol, + UCrypto, Buttons, UPoolMining, URPC, UFRMAccountSelect, UConst, + UAccountKeyStorage, UBaseTypes, UPCDataTypes, UOrderedList, + UFRMRPCCalls, UTxMultiOperation, USettings, UEPasa, + UTime, + UFileStorage, + UThread, + UOpTransaction, + UFRMWalletConfig, + UFRMOperationsExplorer, + {$IFDEF TESTNET} + UFRMRandomOperations, + UFRMDiagnosticTool, + {$ENDIF} + UPCTNetDataExtraMessages, + UFRMAskForAccount, + UAbstractBTree, UEPasaDecoder, + UFRMAbout, + UFRMOperation, + UFRMWalletKeys, + UFRMPayloadDecoder, + UFRMNodesIp, + UFRMMemoText, + UCommon, + UPCOrderedLists, + UWallet; + +procedure TFRMTestWallet.InitMenuForTesting; +var mi : TMenuItem; +begin +{$IFDEF TESTNET} + mi := TMenuItem.Create(MainMenu); + mi.Caption:='-'; + miAbout.Add(mi); + {$IFDEF TESTING_NO_POW_CHECK} + mi := TMenuItem.Create(MainMenu); + mi.Caption:='Create a block'; + mi.OnClick:=Test_CreateABlock; + {$IFnDEF FPC} + mi.ShortCut := TextToShortCut('CTRL+B'); + {$ENDIF} + miAbout.Add(mi); + {$ENDIF} + mi := TMenuItem.Create(MainMenu); + mi.Caption:='Connect/Disconnect'; + mi.OnClick:=Test_ConnectDisconnect; + {$IFnDEF FPC} + mi.ShortCut := TextToShortCut('CTRL+D'); + {$ENDIF} + miAbout.Add(mi); + + mi := TMenuItem.Create(MainMenu); + mi.Caption:='Create Random operations'; + mi.OnClick:=Test_RandomOperations; + miAbout.Add(mi); + mi := TMenuItem.Create(MainMenu); + mi.Caption:='Diagnostic Tool'; + mi.OnClick:=Test_ShowDiagnosticTool; + miAbout.Add(mi); + mi := TMenuItem.Create(MainMenu); + mi.Caption:='Show public keys state'; + mi.OnClick:=Test_ShowPublicKeys; + miAbout.Add(mi); + mi := TMenuItem.Create(MainMenu); + mi.Caption:='Show operations in memory'; + mi.OnClick:=Test_ShowOperationsInMemory; + miAbout.Add(mi); + mi := TMenuItem.Create(MainMenu); + mi.Caption:='Search accounts for private or swap to me'; + mi.OnClick:=Test_FindAccountsForPrivateBuyOrSwapToMe; + miAbout.Add(mi); +{$ELSE} +{$ENDIF} + mi := TMenuItem.Create(MainMenu); + mi.Caption:='-'; + MiOperations.Add(mi); + mi := TMenuItem.Create(MainMenu); + mi.Caption:='Ask for Free Account'; + mi.OnClick:=miAskForAccountClick; + MiOperations.Add(mi); +end; + +{$IFDEF TESTING_NO_POW_CHECK} +procedure TFRMTestWallet.Test_CreateABlock(Sender: TObject); +var ops, mempoolOps : TPCOperationsComp; + nba : TBlockAccount; + errors : String; + +begin + {$IFDEF TESTNET} + ops := TPCOperationsComp.Create(Nil); + Try + ops.bank := FNode.Bank; + mempoolOps := FNode.LockMempoolRead; + try + ops.CopyFrom(mempoolOps); + finally + FNode.UnlockMempoolRead; + end; + ops.BlockPayload.FromString(IntToStr(FNode.Bank.BlocksCount)); + ops.nonce := FNode.Bank.BlocksCount; + ops.UpdateTimestamp; + FNode.AddNewBlockChain(Nil,ops,errors); + finally + ops.Free; + end; + {$ELSE} + Raise Exception.Create('NOT ALLOWED!'); + {$ENDIF} +end; +{$ENDIF} + + + +{$IFDEF TESTNET} + +procedure TFRMTestWallet.Test_ConnectDisconnect(Sender: TObject); +begin + TNetData.NetData.NetConnectionsActive := Not TNetData.NetData.NetConnectionsActive; + Exit; + if FNode.NetServer.Active then begin + FNode.NetServer.Active := False; + end else begin + FNode.NetServer.Active := True; + end; +end; + +procedure TFRMTestWallet.Test_RandomOperations(Sender: TObject); +Var FRM : TFRMRandomOperations; +begin + FRM := TFRMRandomOperations.Create(Self); + Try + FRM.SourceNode := FNode; + FRM.SourceWalletKeys := FWalletKeys; + FRM.ShowModal; + finally + FRM.Free; + end; +end; + +{$ENDIF} + +procedure TFRMTestWallet.Test_ShowOperationsInMemory(Sender: TObject); +var LFRM : TFRMMemoText; + i, nOps : Integer; + Lslist : TStrings; +begin + Lslist := TStringList.Create; + try + TPCOperationsStorage.PCOperationsStorage.GetStats(Lslist); + nOps := TPCOperationsStorage.PCOperationsStorage.Count; + LFRM := TFRMMemoText.Create(Self); + try + LFRM.InitData('Operations in Memory '+IntToStr(nOps),Lslist.Text); + LFRM.ShowModal; + finally + LFRM.Free; + end; + finally + Lslist.Free; + end; +end; + +(* + +// Skybuck: Code is broken ? + +procedure TFRMTestWallet.Test_ShowPublicKeys(Sender: TObject); +var F : TFRMMemoText; + i : Integer; + sl : TStrings; + ak : TAccountKey; + nmin,nmax : Integer; + l : TList; + Pacsd : PAccountKeyStorageData; + acc : TAccount; +begin + sl := TStringList.Create; + try + for i:=0 to FNode.Bank.SafeBox.AccountsCount-1 do begin + acc := FNode.Bank.SafeBox.Account(i); + if acc.accountInfo.new_publicKey.EC_OpenSSL_NID<>0 then begin + sl.Add(Format('Account %d new public key %d %s',[acc.account, + acc.accountInfo.new_publicKey.EC_OpenSSL_NID, + TCrypto.ToHexaString(TAccountComp.AccountKey2RawString(acc.accountInfo.new_publicKey))])); + end; + end; + {$IFnDEF USE_ABSTRACTMEM} + l := TAccountKeyStorage.KS.LockList; + try + sl.Add(Format('%d public keys in TAccountKeyStorage data',[l.count])); + for i:=0 to l.count-1 do begin + Pacsd := l[i]; + if (Pacsd^.counter<=0) then begin + sl.Add(Format('%d/%d public keys counter %d',[i+1,l.count,Pacsd^.counter])); + end; + if FNode.Bank.SafeBox.OrderedAccountKeysList.IndexOfAccountKey(Pacsd^.ptrAccountKey^)<0 then begin + sl.Add(Format('%d/%d public keys counter %d Type %d NOT FOUND %s',[i+1,l.count,Pacsd^.counter, + Pacsd^.ptrAccountKey^.EC_OpenSSL_NID, + TCrypto.ToHexaString(TAccountComp.AccountKey2RawString(Pacsd^.ptrAccountKey^))])); + end; + end; + finally + TAccountKeyStorage.KS.UnlockList; + end; + sl.Add(Format('%d public keys in %d accounts',[FNode.Bank.SafeBox.OrderedAccountKeysList.Count,FNode.Bank.Safebox.AccountsCount])); + for i:=0 to FNode.Bank.SafeBox.OrderedAccountKeysList.Count-1 do begin + ak := FNode.Bank.SafeBox.OrderedAccountKeysList.AccountKey[i]; + if ( FNode.Bank.SafeBox.OrderedAccountKeysList.AccountKeyList[i].Count > 0) then begin + nmin := FNode.Bank.SafeBox.OrderedAccountKeysList.AccountKeyList[i].Get(0); + nmax := FNode.Bank.SafeBox.OrderedAccountKeysList.AccountKeyList[i].Get( FNode.Bank.SafeBox.OrderedAccountKeysList.AccountKeyList[i].Count-1 ); + end else begin + nmin := -1; nmax := -1; + end; + sl.Add(Format('%d/%d %d accounts (%d to %d) for key type %d %s',[ + i+1,FNode.Bank.SafeBox.OrderedAccountKeysList.Count, + FNode.Bank.SafeBox.OrderedAccountKeysList.AccountKeyList[i].Count, + nmin,nmax, + ak.EC_OpenSSL_NID, + TCrypto.ToHexaString(TAccountComp.AccountKey2RawString(ak)) ])); + end; + {$ENDIF} + F := TFRMMemoText.Create(Self); + try + F.InitData('Keys in safebox',sl.Text); + F.ShowModal; + finally + F.Free; + end; + finally + sl.Free; + end; +end; + +*) + +procedure TFRMTestWallet.Test_FindAccountsForPrivateBuyOrSwapToMe(Sender: TObject); +{ This procedure will search in Safebox all accounts in "for_private_sale" state + or in "for_account_swap" that can be self-signed using one of my private keys + } + + function CaptureSender0Coins(var AAccountSender0Coins : TAccount; var ANeededWalletKey : TWalletKey) : Boolean; + var ii : Integer; + begin + // + Result := False; + for ii := 0 to WalletKeys.AccountsKeyList.Count-1 do begin + if WalletKeys.AccountsKeyList.AccountKeyList[ii].Count>0 then begin + if WalletKeys.TryGetKey(WalletKeys.AccountsKeyList.AccountKey[ii],ANeededWalletKey) then begin + AAccountSender0Coins := FNode.Bank.SafeBox.Account( WalletKeys.AccountsKeyList.AccountKeyList[ii].Get(0) ); + Result := True; + end; + end; + end; + + end; + + +var i : Integer; + LLines : TStrings; + LAccount, LAccountSender0Coins : TAccount; + LAccountOpDesc : String; + LCountAccountsFound_total, LCountAccountsFound_Operation : Integer; + LNeededWalletKey : TWalletKey; + s : String; + LOpTransaction : TOpTransaction; + LOperationsHashTree, LGlobalOperationsHashTree : TOperationsHashTree; + LStream : TStream; + LRaw : TRawBytes; + LFRM : TFRMMemoText; + LOpPayload : TOperationPayload; +begin + if Not WalletKeys.IsValidPassword then raise Exception.Create('Your wallet keys are locked'); + LOpPayload := CT_TOperationPayload_NUL; + if InputQuery('Search ATOMIC SWAP by SECRET','Insert SECRET value (use 0x... for Hexadecimal, otherwise will be a String)',s) then begin + if s.StartsWith('0x') then begin + if not UCommon.TryHex2Bytes(s,LOpPayload.payload_raw) then raise Exception.Create('SECRET value is not an Hexadecimal'+#10+s); + end else begin + LOpPayload.payload_raw.FromString(s); + end; + end; + LCountAccountsFound_total := 0; + LCountAccountsFound_Operation := 0; + LLines := TStringList.Create; + LGlobalOperationsHashTree := TOperationsHashTree.Create; + try + for i:=0 to FNode.Bank.SafeBox.AccountsCount-1 do begin + LAccountOpDesc := ''; + LAccount := FNode.Bank.SafeBox.Account(i); + + LOpTransaction := Nil; + Try + Case LAccount.accountInfo.state of + as_ForSale : begin + if Not TAccountComp.IsNullAccountKey( LAccount.accountInfo.new_publicKey ) then begin + if Not WalletKeys.TryGetKey(LAccount.accountInfo.new_publicKey,LNeededWalletKey) then Continue; + if Not Assigned(LNeededWalletKey.PrivateKey) then Continue; // Key not available! + end else Continue; + // Private sale to me + // Is in time? + if TAccountComp.IsAccountLocked(LAccount.accountInfo,FNode.Bank.BlocksCount) then begin + // + if LAccount.balance>=LAccount.accountInfo.price then begin + LAccountOpDesc := Format('Account %s is for private sale to me and with enough balance to pay %s (balance %s)',[ + TAccountComp.AccountNumberToAccountTxtNumber(LAccount.account), + TAccountComp.FormatMoney(LAccount.accountInfo.price), + TAccountComp.FormatMoney(LAccount.balance)]); + // No key needed... just a transaction SELF SIGNED + LOpTransaction := TOpBuyAccount.CreateBuy(FNode.Bank.SafeBox.CurrentProtocol, + LAccount.account, LAccount.n_operation+1, + LAccount.account, LAccount.accountInfo.account_to_pay, LAccount.accountInfo.price, + 0,0, + LAccount.accountInfo.new_publicKey, + LNeededWalletKey.PrivateKey, + LOpPayload); + end else begin + LAccountOpDesc := Format('Account %s is for private sale to me but needs a Buy operation paying %s PASC (%s pending)',[ + TAccountComp.AccountNumberToAccountTxtNumber(LAccount.account), + TAccountComp.FormatMoney(LAccount.accountInfo.price), + TAccountComp.FormatMoney(LAccount.accountInfo.price - LAccount.balance)]); + end; + end else begin + LAccountOpDesc := Format('Account %s is for private sale to me but is out-of-lock period',[TAccountComp.AccountNumberToAccountTxtNumber(LAccount.account)]); + end; + end; + as_ForAtomicAccountSwap : begin + if Not WalletKeys.TryGetKey(LAccount.accountInfo.new_publicKey,LNeededWalletKey) then Continue; + if TAccountComp.IsAccountLocked(LAccount.accountInfo,FNode.Bank.BlocksCount) then begin + if TAccountComp.IsValidAccountInfoHashLockKey(LAccount.accountInfo,LOpPayload.payload_raw) then begin + // Atomic Account swap using provided SECRET + LAccountOpDesc := Format('Account %s is for Atomic Account Swap to me using SECRET %s',[TAccountComp.AccountNumberToAccountTxtNumber(LAccount.account),UCommon.Bytes2Hex(LOpPayload.payload_raw,True)]); + // + // No key needed... just a Buy Operation SELF SIGNED + LOpTransaction := TOpBuyAccount.CreateBuy(FNode.Bank.SafeBox.CurrentProtocol, + LAccount.account, LAccount.n_operation+1, + LAccount.account, LAccount.accountInfo.account_to_pay, LAccount.accountInfo.price, + 0,0, + LAccount.accountInfo.new_publicKey, + LNeededWalletKey.PrivateKey, + LOpPayload); + end else begin + LAccountOpDesc := Format('Account %s is for Atomic Account Swap to me but SECRET %s is not valid',[TAccountComp.AccountNumberToAccountTxtNumber(LAccount.account),UCommon.Bytes2Hex(LOpPayload.payload_raw,True)]); + end; + end else begin + LAccountOpDesc := Format('Account %s is for Atomic Account Swap to me but is out-of-lock period',[TAccountComp.AccountNumberToAccountTxtNumber(LAccount.account)]); + end; + + end; + as_ForAtomicCoinSwap : begin + if Not TAccountComp.IsValidAccountInfoHashLockKey(LAccount.accountInfo,LOpPayload.payload_raw) then Continue; + // Atomic Coin swap using provided SECRET + if TAccountComp.IsAccountLocked(LAccount.accountInfo,FNode.Bank.BlocksCount) then begin + // Single transaction using amount 0 from ANY sender + if CaptureSender0Coins(LAccountSender0Coins,LNeededWalletKey) then begin + // Atomic Account swap using provided SECRET + LAccountOpDesc := Format('Account %s is for Atomic Coin Swap to me using SECRET %s',[TAccountComp.AccountNumberToAccountTxtNumber(LAccount.account),UCommon.Bytes2Hex(LOpPayload.payload_raw,True)]); + // + // No key needed... just a transaction SELF SIGNED + LOpTransaction := TOpTransaction.CreateTransaction(FNode.Bank.SafeBox.CurrentProtocol, + LAccountSender0Coins.account, LAccountSender0Coins.n_operation+1, + LAccount.account, + LNeededWalletKey.PrivateKey, + 0,0, // No Amount no Fee + LOpPayload); + end else begin + LAccountOpDesc := Format('Account %s is for Atomic Coin Swap using SECRET %s but I have no key to sign',[TAccountComp.AccountNumberToAccountTxtNumber(LAccount.account),UCommon.Bytes2Hex(LOpPayload.payload_raw,True)]); + end; + end else begin + LAccountOpDesc := Format('Account %s is for Atomic Coin Swap using SECRET %s but is out-of-lock period',[TAccountComp.AccountNumberToAccountTxtNumber(LAccount.account),UCommon.Bytes2Hex(LOpPayload.payload_raw,True)]); + end; + end; + else Continue; + End; + + // Do + Inc(LCountAccountsFound_total); + LLines.Add(Format('%s',[LAccountOpDesc])); + if Assigned(LOpTransaction) then begin + Inc(LCountAccountsFound_Operation); + LOperationsHashTree := TOperationsHashTree.Create; + LStream := TMemoryStream.Create; + try + LOperationsHashTree.AddOperationToHashTree(LOpTransaction); + LGlobalOperationsHashTree.AddOperationToHashTree(LOpTransaction); + LLines.Add(Format('Operation: %s',[LOpTransaction.ToString])); + LOperationsHashTree.SaveOperationsHashTreeToStream(LStream,False); + LRaw.FromStream(LStream); + LLines.Add(Format('rawoperations (for JSON-RPC call): %s',[LRaw.ToHexaString])); + finally + LOperationsHashTree.Free; + LStream.Free; + end; + end; + + Finally + FreeAndNil(LOpTransaction); + End; + end; // For + LLines.Add(''); + LLines.Add(Format('Found %d of %d available account from a Safebox with %d accounts',[ + LCountAccountsFound_Operation, + LCountAccountsFound_total, + FNode.Bank.SafeBox.AccountsCount])); + LStream := TMemoryStream.Create; + try + LGlobalOperationsHashTree.SaveOperationsHashTreeToStream(LStream,False); + LRaw.FromStream(LStream); + LLines.Add(Format('rawoperations (for JSON-RPC call) of %d operations: %s',[LGlobalOperationsHashTree.OperationsCount, LRaw.ToHexaString])); + finally + LStream.Free; + end; + // + LFRM := TFRMMemoText.Create(Self); + try + LFRM.InitData('',LLines.Text); + LFRM.ShowModal; + finally + LFRM.Free; + end; + finally + LLines.Free; + LGlobalOperationsHashTree.Free; + end; +end; + +procedure TFRMTestWallet.Test_ShowDiagnosticTool(Sender: TObject); +{$IFDEF TESTNET} +var + LDialog : TFRMDiagnosticTool; +{$ENDIF} +begin +{$IFDEF TESTNET} + LDialog := TFRMDiagnosticTool.Create(Nil); + try + LDialog.ShowModal; + finally + LDialog.Free; + end; +{$ENDIF} +end; + + +procedure TFRMTestWallet.FormCreate(Sender: TObject); +begin + inherited; + + // Things for testing purposes only + InitMenuForTesting; +end; + +end. diff --git a/src/gui-classic/UFRMWallet.dfm b/src/gui-classic/UFRMWallet.dfm index 03a44e53b..fc3981224 100644 --- a/src/gui-classic/UFRMWallet.dfm +++ b/src/gui-classic/UFRMWallet.dfm @@ -23,333 +23,30 @@ object FRMWallet: TFRMWallet Left = 0 Top = 0 Width = 865 - Height = 91 + Height = 108 Align = alTop BevelOuter = bvNone TabOrder = 0 - object Image1: TImage - Left = 15 - Top = 15 - Width = 64 - Height = 64 - AutoSize = True - Picture.Data = { - 0954506E67496D61676589504E470D0A1A0A0000000D49484452000000400000 - 00400806000000AA6971DE0000000467414D410000B18F0BFC61050000000970 - 48597300000EC200000EC20115284A800000001874455874536F667477617265 - 007061696E742E6E657420342E312E36FD4E09E800000AD54944415478DAD55B - 0B7854C515FE67EEDD17848780402860B21BE4258A8116FD1004A4F889852282 - A808A2541113146DB5AD521A3EABD54AA186243E2A55D17E060111A42A5A9487 - F8E04D4185920DB18809280884ECFBCEF4DC0D6CB264F766B30F361EF86EF6EE - 3DF3F8FF397BE6CCB9334C4A89944A415FB3BF93B79F4F139733C97A32862C06 - 7402581B6AD9060649FF3C7439C1192A85645F7326BFD2A0ED6AF95DD65E14AC - 0FA4B27B2C1504B84B72BA494DDEC0384613B8218CB116F1D4437DAB26823630 - 897F694C7BAB655E4555B32560FB0B034D7D7CC7C7017C06757A388D324F6647 - C9420290EC7D29C4732D320FBE8389526B1E0410708FF7C434C9E42334D259C9 - 041D950C29F7D3E54FB6CE075F4F94888408A829768CE6600B69B42F3E1FC023 - 50B15B61E27ED3BD07379C5F025EE8D9C1E50B1473C66E4A0FF07A14D06F839C - E662B3C67FCDEE3B702AE504788A728651A97F52D12EE9061F4E842C975CDEDC - E2DEF2AD292380C0CFA2DFFA0206A6A61B70441220BD749961CB77BE92640218 - F314DBE7D3DF07530980B5EB09D6BE07E03D09ED7F1F074384FAC2330702199D - 21ABBF85ACDA118584E0FFB9B6FCF2C71103B8180860CC5BEC2821AD7B52091E - ADBBC17AEB0780526B5CBE8DF320F6BC5AD78B6E436119FB8F332825BC6F4D81 - FCF633830AC553D6BCF2DF254C80A7C8B180387820A5E049949EE3601A393F74 - EFDF58006DCF6BA17BF5CA87A0E6CE08DD7B57DE4A046C69041CE658F2CB1E8F - 9B006F91E37EC9D8DF520D3E08F0AA39502F9B16BAF7AD980851B533746F1AF3 - 3294EE57D5DED0D4EFFE7B2E98BFC6B04E7D8600D36EB7E51D7C359A4E54023C - 2539C3A5901F5070A3843DC8E802F3354F20E97EB0FDC5E0D676A15B51B51DD0 - FC751DED781998C976E66100A2721BA4D0204F7E0D796417F98C4D80EBBB4835 - BB158E21A69965DB6326E0F4B38E8EAA865D64FA99618CAA2D60B971297887DE - C9059F0C21ABD00E6D46605B3164653856C25856E332E57678785F754C04B88B - 1CCB68E427845542A1BDF9BA1228F691E986DA1813087CB914810DF3C852EA2C - 88603E6FCB2F6BE0C81B10E02AB48FE10A5F7DAEA27AE5C3E484EE4E37BA9845 - 73AE85EFBDFCD0544A57012187DA6639374725E040610F4B572EF6D2E8E7D457 - 527A8D8769C453FA8C986E5C4D12DF477320BE2C0DDD13D4EDB6EF9D3F438114 - 1109A0606726851B25610C650E8069EC1270D5926E3C4D1671EA10BCAF8E080B - A824B449342BBCD180802F0AFA9AB33B780F7086EE216D732B98473F0BD4F3CE - CD4AAC6DC15B763454F1965E0F796C7F1D0152FE87A2C4FE417BA84F807B51CE - 24C6518A1F91A8FDEF803AF851431DDFEAA910873E09FF528A51D6FCF20FC209 - 28767C448B9C61E906755E08805C61CD734E0811F04371F6455628E5C94E6335 - 5702F455A3D7AF756E3BBBE244900057916336676C6142BD69D515A621730C55 - 84F35D68FB57258D00A5DF6D300D2D683201B5246853F510394800053E6B69EA - 1B954867F8C5E360FEF97C431DDFFBB3210EAC491E01974C86E9EA7971114052 - 6ACD2BBB85C93FF631BB3B787E8837757D56D42173A15E3AD550C7B3641850FD - 4DF32040A2CA9A5F96C96A4A1C03B8C0B6443B631AFF0694CCDCA8CF85E738BC - 8B073548722444C0A5B7D3CFEE0FF11110EC94DFCEDC85D9D3C1F98B89744472 - 132CBFDA096EB246D5D1576BFEB7EF481A785D4C239E84D27B82A18E110142CA - F1CCBDC8F1171A968712EA49FBDEB0DEFCB6A18A9F5669DAE789F9D9FAC23AF6 - 83F986525A951B47A84604D06CF07B56B3C8BE34D1F436EF3309E6E1868917F8 - B716421EFE2CC61AA3C2066CEDC0BB0C82AA8FBC6A6DB4846FD514886F3E8D4C - 80C073CC55644F380052873D0EB5EFA404C1A5408420C73B04A83912F9B9C49B - CCB5C8BE836680CB1369C77CD36AF00BFBA41B6E43FC95DBE17B33FAC05004B0 - 8E7C807D2F2D73FBC6DD8A6A83951CE0D96C6EB3111A7DEFAADB8C13A7526E60 - 1404EDA18F97C4DB0EEBD41F9609CBD30DF75C64F06F7E0ADAAE4626379D00D7 - 22C716C6F0D3789B52FA4DA570746EBA118744D41C4560D363C1B0BB719AE45A - DD072414069B463E0DA5E70DE9451DF0401CDD0DEDBF6B68ADB132781F135914 - 0EEB16F01259C0B4B809B8652D94768EE88D545722F0C91361DFA9B9F790D33C - E376C813F9D73F02E93B1D7A6ED6C3DB334918E9AD0E3E8F248CE63171EA30E4 - 0F6531830E17B940B780B96401F3E2281DCC1859A76FA74020FA2A5A94BD03DF - DAFBC2BEB3DEBE31F87E21F8BCE63B785FBE1267B38DD2D412B6BB7610BADAD7 - 11DAE1CFE17F6B725CDD6B4CC84FCE623545D91338F8B2782AE03FB902E671AF - 19EAF8373F19E68C180532963B3F07CE40D6BEDE00FF9AE975CF3BE7C2726328 - 6587C0AEC5086CFE734A08A058F81A76624177BBC56C72C6535EE97F174C837F - 6BA873EE3B3C49D19B65D21AF0B659C19719BE0F1F81D8B7A2AE40ABAE304F5C - 096EBB00D2EF868FD60FB232E1B55A03D1D3E4367FA03DA30F7A2C70989DF316 - 2816315D5B0825677474052D00F78BB960015778E364DEBC457B48FD77EB6DB8 - A9432A16706B9B5ABFE077211522A5FCC296EFBC249810F1143996503034A589 - 0CC232652378EBE81B45C4F103F0BD7E5D4A00244C8010CFD86695CF3E9311B2 - 4F648CBFD1A41A6CED61BD535FDC447F5912D8B7128175892D345348C1486B9E - 735D9080A3C57D335A4B4F25594146ACC579F7AB611EB3D850E7DC4D0ECD46A4 - ACB2762AEFAA6FB1AB4B8B173916931FB833D63A948179300D32DE37E15D7E23 - E491DDE9861B8981F934FA41D30C11E02A720C2402B630239BAE27A6D1CF43C9 - BE26BA42C0470EF07230CD9B6EB4E7820F40E3BDACF71D708611A00B59C18744 - C2F046AB208E2CD33E016F7961541DEDE85EF8978D4B37DA48BD5F46A31F4A00 - 8513509C3D948C7B7DA356909149D1DC264395C0DE52043618BF2738EFD0A5D4 - 1405FDCD339D7B2312102461916315E36CAC51453C7B14CCA34B8C546A039CAF - 9A36B1A49C00E0255B5E59989F6B40C0C9C21E0EB322F7E8D9B76815A957FC06 - EA00E35D73DED25F401EDB976ECCF5E11F0F04649F8CFBCBC3F26351B6C8D81F - A4B8E0AFD1AA328D7D054AB7C1519B123E17BCBA034CCE8EF6E4C097725AA41D - A49177892D638AFBA8FD3D06D6704310E3B04CDF0A666913B531AD7207FC6FA6 - 7D1F757DF0CB09FCC448CFA26E93AB29CEEAAC40D94A2A5DC30AB4C982E5B67F - 1B3618D8FD0A021F3F966EDC67C1EFF79831E882BB9D279B44802EAE67730670 - 4DAE0F8B10DB66436D2403242AD641348B00481E637E31D832FBE0FE681A316C - 95CDB95632B98A7E0E3FAE4D42529EA67865942DBFEC5323B598768B7B4BECD7 - 0BC1973386C65FC5340B91A768CDFD4B6B7ED9FAC634633E2FE029CC190E8E15 - 14225D906E788DC811C1C498580F4E34E9C0447549566F55282B295CEE996E94 - 9145EE845F1B6F9D5D51116B89261F993956D8A3754B2E4AC831A62653190F6C - 7D57B814CFDB5A890730ADA249E9E1B84F8DB90AED13B8C29E49F7D921427E90 - 1CF4BDD6BCB2F7E2299FD0B1B95A6B908F4A865946A1734A80EBA74A81F9569F - EF69F6E02177BCF524E5E468CDC28B32B9497D886689E95465EB14033F4E643F - 6735AB0B71F7FEEF13AD2FA96787E5E25EADDC6EFF640E4C918C5D91AC7D87FA - 32966C7D1311BCE4F8F7EEA55D0ABE4D5AAA382587A7839D2EEADEC50B55CF99 - 8FD0C9A0A6B262CD3605B7B6034EEADCA7F4F9434DC1BB19339D4753D1CF9411 - D0405E70B471F9955E4C882CCE652721D13618589117231FE2A1CB0972665592 - 6B15AED3E67D914E77A442FE0F6724BE5B75E29AC60000000049454E44AE4260 - 82} - end - object lblCurrentBlockCaption: TLabel - Left = 90 - Top = 11 - Width = 60 - Height = 13 - Caption = 'Total Blocks:' - Color = clBtnFace - ParentColor = False - end - object lblCurrentBlock: TLabel - Left = 166 - Top = 11 - Width = 18 - Height = 13 - Caption = '000' - Color = clBtnFace - ParentColor = False - end - object lblCurrentBlockTimeCaption: TLabel - Left = 90 - Top = 26 - Width = 90 - Height = 13 - Caption = 'Current Block Age:' - Color = clBtnFace - ParentColor = False - end - object lblCurrentBlockTime: TLabel - Left = 198 - Top = 26 - Width = 81 - Height = 13 - Caption = '000 seconds ago' - Color = clBtnFace - ParentColor = False - end - object lblOperationsPendingCaption: TLabel - Left = 90 - Top = 41 - Width = 98 - Height = 13 - Caption = 'Pending Operations:' - Color = clBtnFace - ParentColor = False - end - object lblOperationsPending: TLabel - Left = 207 - Top = 41 - Width = 18 - Height = 13 - Caption = '000' - Color = clBtnFace - ParentColor = False - end - object lblMiningStatusCaption: TLabel - Left = 90 - Top = 56 - Width = 65 - Height = 13 - Caption = 'Miner Clients:' - Color = clBtnFace - ParentColor = False - end - object lblMinersClients: TLabel - Left = 177 - Top = 56 - Width = 18 - Height = 13 - Caption = '000' - Color = clBtnFace - ParentColor = False - end - object lblCurrentDifficultyCaption: TLabel - Left = 429 - Top = 11 - Width = 76 - Height = 13 - Caption = 'Current Target:' - Color = clBtnFace - ParentColor = False - end - object lblCurrentDifficulty: TLabel - Left = 518 - Top = 11 - Width = 18 - Height = 13 - Caption = '000' - Color = clBtnFace - ParentColor = False - end - object lblTimeAverage: TLabel - Left = 370 - Top = 26 - Width = 18 - Height = 13 - Caption = '000' - Color = clBtnFace - ParentColor = False - end - object Label4: TLabel - Left = 285 - Top = 26 - Width = 69 - Height = 13 - Caption = 'Time average:' - Color = clBtnFace - ParentColor = False - end - object Label8: TLabel - Left = 90 - Top = 70 - Width = 63 - Height = 13 - Caption = 'Node Status:' - Color = clBtnFace - ParentColor = False - end - object lblNodeStatus: TLabel - Left = 168 - Top = 70 - Width = 15 - Height = 13 - Caption = '???' - Color = clBtnFace - ParentColor = False - end - object Label5: TLabel - Left = 285 - Top = 11 - Width = 48 - Height = 13 - Caption = 'Accounts:' - Color = clBtnFace - ParentColor = False - end - object lblCurrentAccounts: TLabel - Left = 344 - Top = 11 - Width = 18 - Height = 13 - Caption = '000' - Color = clBtnFace - ParentColor = False - end - object lblTimeAverageAux: TLabel - Left = 370 - Top = 41 - Width = 18 - Height = 13 - Caption = '000' - Color = clBtnFace - Font.Charset = DEFAULT_CHARSET - Font.Color = clGray - Font.Height = -11 - Font.Name = 'Tahoma' - Font.Style = [] - ParentColor = False - ParentFont = False - end - object Label16: TLabel - Left = 360 - Top = 56 - Width = 76 - Height = 13 - Caption = 'Blocks Found:' - Color = clBtnFace - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = -11 - Font.Name = 'Tahoma' - Font.Style = [fsBold] - ParentColor = False - ParentFont = False - end - object lblBlocksFound: TLabel - Left = 450 - Top = 56 - Width = 21 - Height = 13 - Hint = 'Blocks found while Miner is running...' - Caption = '000' - Color = clBtnFace - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = -11 - Font.Name = 'Tahoma' - Font.Style = [fsBold] - ParentColor = False - ParentFont = False - ParentShowHint = False - ShowHint = True - end - object lblReceivedMessages: TLabel - Left = 360 - Top = 66 - Width = 184 - Height = 23 - Cursor = crHandPoint - Caption = 'Received Messages' - Color = clBtnFace - Font.Charset = DEFAULT_CHARSET - Font.Color = clRed - Font.Height = -19 - Font.Name = 'Tahoma' - Font.Style = [fsBold] - ParentColor = False - ParentFont = False - OnClick = lblReceivedMessagesClick - end - object lblBuild: TLabel - Left = 586 - Top = 3 - Width = 49 - Height = 23 - Caption = 'Build' - Color = clBtnFace - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = -19 - Font.Name = 'Tahoma' - Font.Style = [fsBold] - ParentColor = False - ParentFont = False + inline FrameInfo: TFrameInfo + Left = 0 + Top = 0 + Width = 865 + Height = 108 + Align = alTop + TabOrder = 0 + ExplicitWidth = 865 + inherited Panel1: TPanel + inherited Image1: TImage + Width = 71 + Height = 104 + ExplicitWidth = 75 + ExplicitHeight = 104 + end + end + inherited Panel4: TPanel + Width = 301 + ExplicitWidth = 301 + end end end object StatusBar: TStatusBar @@ -374,843 +71,330 @@ object FRMWallet: TFRMWallet end object PageControl: TPageControl Left = 0 - Top = 91 + Top = 108 Width = 865 - Height = 466 + Height = 449 ActivePage = tsMyAccounts Align = alClient TabOrder = 2 OnChange = PageControlChange object tsMyAccounts: TTabSheet Caption = 'Account Explorer' - object Splitter1: TSplitter - Left = 400 - Top = 66 - Width = 5 - Height = 372 - ExplicitHeight = 374 - end - object pnlMyAccountsTop: TPanel + inline FrameAccountExplorer: TFrameAccountExplorer Left = 0 Top = 0 Width = 857 - Height = 66 - Align = alTop - BevelOuter = bvNone + Height = 421 + Align = alClient TabOrder = 0 - object Label18: TLabel - Left = 11 - Top = 35 - Width = 61 - Height = 13 - Caption = 'Find account' - Color = clBtnFace - ParentColor = False - end - object sbSearchAccount: TSpeedButton - Left = 176 - Top = 32 - Width = 23 - Height = 22 - Glyph.Data = { - 36030000424D3603000000000000360000002800000010000000100000000100 - 18000000000000030000120B0000120B00000000000000000000FF00FF4A667C - BE9596FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 - FFFF00FFFF00FFFF00FF6B9CC31E89E84B7AA3C89693FF00FFFF00FFFF00FFFF - 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF4BB4FE51B5FF - 2089E94B7AA2C69592FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 - FFFF00FFFF00FFFF00FFFF00FF51B7FE51B3FF1D87E64E7AA0CA9792FF00FFFF - 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF - 51B7FE4EB2FF1F89E64E7BA2B99497FF00FFFF00FFFF00FFFF00FFFF00FFFF00 - FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF52B8FE4BB1FF2787D95F6A76FF - 00FFB0857FC09F94C09F96BC988EFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF - FF00FFFF00FF55BDFFB5D6EDBF9D92BB9B8CE7DAC2FFFFE3FFFFE5FDFADAD8C3 - B3B58D85FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFCEA795FD - EEBEFFFFD8FFFFDAFFFFDBFFFFE6FFFFFBEADDDCAE837FFF00FFFF00FFFF00FF - FF00FFFF00FFFF00FFFF00FFC1A091FBDCA8FEF7D0FFFFDBFFFFE3FFFFF8FFFF - FDFFFFFDC6A99CFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFC1A091FEE3ACF1 - C491FCF2CAFFFFDDFFFFE4FFFFF7FFFFF7FFFFE9EEE5CBB9948CFF00FFFF00FF - FF00FFFF00FFFF00FFC2A191FFE6AEEEB581F7DCAEFEFDD8FFFFDFFFFFE3FFFF - E4FFFFE0F3ECD2BB968EFF00FFFF00FFFF00FFFF00FFFF00FFBC978CFBE7B7F4 - C791F2C994F8E5B9FEFCD8FFFFDDFFFFDCFFFFE0E2D2BAB68E86FF00FFFF00FF - FF00FFFF00FFFF00FFFF00FFD9C3A9FFFEE5F7DCB8F2C994F5D4A5FAE8BDFDF4 - C9FDFBD6B69089FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFB58D85E8 - DEDDFFFEF2F9D8A3F4C48CF9D49FFDEAB8D0B49FB89086FF00FFFF00FFFF00FF - FF00FFFF00FFFF00FFFF00FFFF00FFAD827FC9AA9EEFE0B7EFDFB2E7CEACB890 - 86B89086FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF - 00FFFF00FFBA968ABB988CB79188FF00FFFF00FFFF00FFFF00FF} - OnClick = sbSearchAccountClick - end - object cbMyPrivateKeys: TComboBox - Left = 260 - Top = 7 - Width = 411 - Height = 21 - Style = csDropDownList - TabOrder = 0 - OnChange = cbMyPrivateKeysChange - end - object cbExploreMyAccounts: TCheckBox - Left = 11 - Top = 10 - Width = 235 - Height = 19 - Caption = 'Explore accounts with one of my Wallet Keys' - TabOrder = 1 - OnClick = cbExploreMyAccountsClick - end - object ebFindAccountNumber: TEdit - Left = 87 - Top = 33 - Width = 83 - Height = 21 - TabOrder = 3 - OnChange = ebFindAccountNumberChange - OnExit = ebFindAccountNumberExit - end - object bbChangeKeyName: TBitBtn - Left = 685 - Top = 5 - Width = 126 - Height = 25 - Caption = 'Change Key name' - TabOrder = 2 - OnClick = bbChangeKeyNameClick - end - object cbFilterAccounts: TCheckBox - Left = 260 - Top = 35 - Width = 145 - Height = 19 - Caption = 'Filter accounts by balance' - TabOrder = 4 - OnClick = cbFilterAccountsClick + ExplicitWidth = 857 + ExplicitHeight = 421 + inherited Splitter1: TSplitter + Height = 355 + ExplicitHeight = 359 end - object ebFilterAccountByBalanceMin: TEdit - Left = 412 - Top = 33 - Width = 83 - Height = 21 - Hint = 'Min balance' - TabOrder = 5 - OnExit = ebFilterAccountByBalanceMinExit - OnKeyPress = ebFilterAccountByBalanceMinKeyPress + inherited pnlMyAccountsTop: TPanel + Width = 857 + ExplicitWidth = 857 end - object ebFilterAccountByBalanceMax: TEdit - Left = 503 - Top = 33 - Width = 83 - Height = 21 - Hint = 'Max balance' - TabOrder = 6 - OnExit = ebFilterAccountByBalanceMinExit - OnKeyPress = ebFilterAccountByBalanceMinKeyPress - end - end - object pnlAccounts: TPanel - Left = 0 - Top = 66 - Width = 400 - Height = 372 - Align = alLeft - BevelOuter = bvNone - TabOrder = 1 - object dgAccounts: TDrawGrid - Left = 0 - Top = 0 - Width = 400 - Height = 338 - Align = alClient - TabOrder = 0 - OnClick = dgAccountsClick - end - object pnlAccountsInfo: TPanel - Left = 0 - Top = 338 - Width = 400 - Height = 34 - Align = alBottom - BevelOuter = bvNone - TabOrder = 1 - DesignSize = ( - 400 - 34) - object Label17: TLabel - Left = 5 - Top = 10 - Width = 48 - Height = 13 - Caption = 'Accounts:' - Color = clBtnFace - ParentColor = False - end - object Label19: TLabel - Left = 136 - Top = 10 - Width = 41 - Height = 13 - Caption = 'Balance:' - Color = clBtnFace - ParentColor = False - end - object lblAccountsCount: TLabel - Left = 60 - Top = 10 - Width = 18 - Height = 13 - Caption = '000' - Color = clBtnFace - ParentColor = False - end - object lblAccountsBalance: TLabel - Left = 200 - Top = 10 - Width = 18 - Height = 13 - Caption = '000' - Color = clBtnFace - ParentColor = False - end - object bbAccountsRefresh: TBitBtn - Left = 322 - Top = 6 - Width = 75 - Height = 25 - Anchors = [akTop, akRight] - Caption = 'Refresh' - Glyph.Data = { - 36030000424D3603000000000000360000002800000010000000100000000100 - 18000000000000030000120B0000120B00000000000000000000FF00FFFF00FF - C2A6A4C2A6A4C2A6A4C2A6A4C2A6A4C2A6A4C2A6A4C2A6A4C2A6A4C2A6A4C2A6 - A4C2A6A4FF00FFFF00FFFF00FFFF00FFC2A6A4FEFCFBFEFCFBFEFCFBFEFCFBFE - FCFBFEFCFBFEFCFBFEFCFBFEFCFBFEFCFBC2A6A4FF00FFFF00FFFF00FFFF00FF - C2A6A4FEFCFBFEFCFBFEFCFBFEFCFBD8EBD6018A02018A02D8EBD6FEFCFBFEFC - FBC2A6A4FF00FFFF00FFFF00FFFF00FFC2A6A4FEFBF7FEFBF7018A02D8EAD201 - 8A02D8EAD2D8EAD2018A02FEFBF7FEFBF7C2A6A4FF00FFFF00FFFF00FFFF00FF - C2A6A4FEF9F4FEF9F4018A02018A02D8E8D0FEF9F4FEF9F4D8E8D0FEF9F4FEF9 - F4C2A6A4FF00FFFF00FFFF00FFFF00FFC2A6A4FEF7F0FEF7F0018A02018A0201 - 8A02FEF7F0FEF7F0FEF7F0FEF7F0FEF7F0C2A6A4FF00FFFF00FFFF00FFFF00FF - C2A6A4FEF5ECFEF5ECFEF5ECFEF5ECFEF5EC018A02018A02018A02FEF5ECFEF5 - ECC2A6A4FF00FFFF00FFFF00FFFF00FFC2A6A4FEF3E9FEF3E9D8E3C7FEF3E9FE - F3E9D8E3C7018A02018A02FEF3E9FEF3E9C2A6A4FF00FFFF00FFFF00FFFF00FF - C2A6A4FFF1E5FFF1E5018A02D9E2C3D9E2C3018A02D9E2C3018A02FFF1E5FFF1 - E5C2A6A4FF00FFFF00FFFF00FFFF00FFC2A6A4FFF0E2FFF0E2D9E1C1018A0201 - 8A02D9E1C1DDCFC2DDCFC2DDCFC2DDCFC2C2A6A4FF00FFFF00FFFF00FFFF00FF - C2A6A4FFEEDEFFEEDEFFEEDEFFEEDEFFEEDEFFEEDEC5B5A9C3B4A8C2B3A7C1B2 - A6C2A6A4FF00FFFF00FFFF00FFFF00FFC2A6A4FFECDAFFECDAFFECDAFFECDAFF - ECDAFFECDAB0A296B0A296B0A296B0A296C2A6A4FF00FFFF00FFFF00FFFF00FF - C2A6A4FFEAD7FFEAD7FFEAD7FFEAD7FFEAD7C9B9ACFBF8F4FBF8F4E6DAD9C2A6 - A4FF00FFFF00FFFF00FFFF00FFFF00FFC2A6A4FFE8D3FFE8D3FFE8D3FFE8D3FF - E8D3C9B9ACFBF8F4DFCEC7C2A6A4FF00FFFF00FFFF00FFFF00FFFF00FFFF00FF - C2A6A4FFE6D0FFE6D0FFE6D0FFE6D0FFE6D0C9B9ACDFCEC7C2A6A4FF00FFFF00 - FFFF00FFFF00FFFF00FFFF00FFFF00FFC2A6A4C2A6A4C2A6A4C2A6A4C2A6A4C2 - A6A4C2A6A4C2A6A4FF00FFFF00FFFF00FFFF00FFFF00FFFF00FF} - TabOrder = 0 - OnClick = bbAccountsRefreshClick + inherited pnlAccounts: TPanel + Height = 355 + ExplicitHeight = 355 + inherited dgAccounts: TDrawGrid + Height = 321 + ExplicitHeight = 321 end - end - end - object pcAccountsOptions: TPageControl - Left = 405 - Top = 66 - Width = 452 - Height = 372 - ActivePage = tsAccountOperations - Align = alClient - TabOrder = 2 - object tsAccountOperations: TTabSheet - Caption = 'Account Operations' - object dgAccountOperations: TDrawGrid - Left = 0 - Top = 0 - Width = 444 - Height = 344 - Align = alClient - TabOrder = 0 - OnDblClick = MiDecodePayloadClick + inherited pnlAccountsInfo: TPanel + Top = 321 + ExplicitTop = 321 end end - object tsMultiSelectAccounts: TTabSheet - Caption = 'Selected Accounts For Batch Operation' - ImageIndex = 1 - object dgSelectedAccounts: TDrawGrid - Left = 41 - Top = 31 - Width = 320 - Height = 287 - Align = alLeft - TabOrder = 0 - end - object pnlSelectedAccountsTop: TPanel - Left = 0 - Top = 0 - Width = 444 - Height = 31 - Align = alTop - BevelOuter = bvNone - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = -13 - Font.Name = 'Tahoma' - Font.Style = [fsBold] - ParentFont = False - TabOrder = 1 - object Label15: TLabel - Left = 41 - Top = 4 - Width = 361 - Height = 16 - Caption = 'Select multiple accounts to execute massive operations' - Color = clBtnFace - ParentColor = False + inherited pcAccountsOptions: TPageControl + Width = 452 + Height = 355 + ExplicitWidth = 452 + ExplicitHeight = 355 + inherited tsMultiSelectAccounts: TTabSheet + ExplicitWidth = 444 + ExplicitHeight = 327 + inherited dgSelectedAccounts: TDrawGrid + Height = 270 + ExplicitHeight = 270 end - end - object pnlSelectedAccountsBottom: TPanel - Left = 0 - Top = 318 - Width = 444 - Height = 26 - Align = alBottom - BevelOuter = bvNone - TabOrder = 2 - object Label20: TLabel - Left = 41 - Top = 6 - Width = 48 - Height = 13 - Caption = 'Accounts:' - Color = clBtnFace - ParentColor = False - end - object lblSelectedAccountsCount: TLabel - Left = 96 - Top = 6 - Width = 18 - Height = 13 - Caption = '000' - Color = clBtnFace - ParentColor = False + inherited pnlSelectedAccountsTop: TPanel + Width = 444 + ExplicitWidth = 444 end - object Label22: TLabel - Left = 156 - Top = 6 - Width = 88 - Height = 13 - Caption = 'Accounts Balance:' - Color = clBtnFace - ParentColor = False + inherited pnlSelectedAccountsBottom: TPanel + Top = 301 + Width = 444 + ExplicitTop = 301 + ExplicitWidth = 444 end - object lblSelectedAccountsBalance: TLabel - Left = 250 - Top = 6 - Width = 18 - Height = 13 - Caption = '000' - Color = clBtnFace - ParentColor = False + inherited pnlSelectedAccountsLeft: TPanel + Height = 270 + ExplicitHeight = 270 end end - object pnlSelectedAccountsLeft: TPanel - Left = 0 - Top = 31 - Width = 41 - Height = 287 - Align = alLeft - BevelOuter = bvNone - TabOrder = 3 - object sbSelectedAccountsAdd: TSpeedButton - Left = 2 - Top = 0 - Width = 33 - Height = 31 - Caption = '>' - OnClick = sbSelectedAccountsAddClick - end - object sbSelectedAccountsAddAll: TSpeedButton - Left = 2 - Top = 37 - Width = 33 - Height = 31 - Caption = '>>' - OnClick = sbSelectedAccountsAddAllClick - end - object sbSelectedAccountsDel: TSpeedButton - Left = 2 - Top = 74 - Width = 33 - Height = 31 - Caption = '<' - OnClick = sbSelectedAccountsDelClick - end - object sbSelectedAccountsDelAll: TSpeedButton - Left = 2 - Top = 111 - Width = 33 - Height = 31 - Caption = '<<' - OnClick = sbSelectedAccountsDelAllClick - end - end - object bbSelectedAccountsOperation: TBitBtn - Left = 367 - Top = 31 - Width = 75 - Height = 61 - Caption = 'Operations' - Glyph.Data = { - F6060000424DF606000000000000360000002800000018000000180000000100 - 180000000000C0060000120B0000120B00000000000000000000FF00FFFF00FF - FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 - FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF - 00FFFF00FFFF00FF019ACF019ACF019ACF019ACFFF00FFFF00FFFF00FFFF00FF - FF00FFFF00FFFF00FFFF00FFFF00FFFF00FF0C8518FF00FFFF00FFFF00FFFF00 - FFFF00FFFF00FFFF00FFFF00FF0D9FD18BD4EE6BD3F845C0ED28B0E0019ACF01 - 9ACF019ACF019ACFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF0C85180C8518 - FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF069CD076C8E5A9E9FE6DD8 - FF75DBFF77DCFF77DBFF63D1F930B3E3029BD0019ACF019ACF019ACF019ACFFF - 00FF0C85181399220C8518FF00FFFF00FFFF00FFFF00FFFF00FFFF00FF019ACF - 34AFD9BCE9F86ED8FF6FD8FE70D8FE70D8FE71D8FF0C85180C85180C85180C85 - 180C85180C85180C85180C85181DAC31139A220C8518FF00FFFF00FFFF00FFFF - 00FFFF00FF019ACF1FA9D68FD3EB97E4FF6FD9FE71D9FE71D9FE71D9FE0C8518 - 57E38851DD7E4AD77443D0693BC95E34C1522BBA4725B33C1EAE33149B230C85 - 18FF00FFFF00FFFF00FFFF00FF019ACF31B1DC49B7DEBDEEFB71DDFE77DEFE77 - DEFE77DEFE0C85185EE89059E48953DE804CD87645D16C3DCA6035C2542DBB49 - 26B53F1FAF35149B250C8518FF00FFFF00FFFF00FF019ACF52C2E71DA7D5ADE2 - F38FE8FF7CE2FE7CE3FE7CE3FE0C851861EB955FE9925AE58B54DF824DD97846 - D26D3ECB6237C4562FBD4C27B64021B037159B250C8518FF00FFFF00FF019ACF - 60CAEF1FA8D85EC1E1C2E6ED8ACEE08FCFE18ECFE10C851861EB9561EB955FEA - 935CE58D56E0844FDB7A48D47040CD6538C65931BF4D1DA3320C8518FF00FFFF - 00FFFF00FF019ACF65CFF53EB7E52CA9D4C5EFF8ACF3FEA5F2FFA5F2FF0C8518 - 61EB9561EB9561EB9561EB945CE68E57E18650DC7C49D57242CE6727AD410C85 - 18FF00FFFF00FFFF00FFFF00FF019ACF69D1F855C4F32A9CC673CBE7D6FEFDB1 - FBFDB2FBFD0C85180C85180C85180C85180C85180C85180C85180C851852DD7F - 32B6500C851898FAFF019ACFFF00FFFF00FFFF00FF019ACF77D5FC5CC8FB748E - A224A8D5B9E7F3D5F5F9D5F6F9D6F6FADCFAFBCDFDFCB9FCFCAFFAFCB0FAFCB1 - FAFC0C85183ABE5C0C85189FFCFFA4FFFF43C1E2019ACFFF00FFFF00FF019ACF - 8BDBFF5FCDFFB7898973C3DD18A2D218A2D216A2D215A1D21AA4D391D7EBEBFE - FDDBFDFCC5FBFBC2FBFB0C85180C851883E4F3B6FDFFBAFFFFB5FCFD019ACFFF - 00FFFF00FF019ACF99E2FF67D3FFB88989FEF5ECFDF3EBF0EFEAE5EBE8D6E5E6 - A4D2E025A6D34DB9DDE5F8FBF5FDFCEBFCFB0C8518C4FBFF9CE4F2DAFEFFD9FE - FFE3FFFFADE9F5019ACFFF00FF019ACF9FE9FF70DCFFB88989FEF3E9FFF2E6FE - F3E9FEF3E9FEF3E9FEF3E9D4E4E439ADD422A5D49DD8ECF1F9FBEEEFEFE9FDFF - CEEEF7F8FFFFF7FFFFFEFFFFE9F9FD019ACFFF00FF019ACFA7EFFF76E5FFB889 - 89FFF2E5FFF0E2FFF2E5FFF2E5FFF2E5FFF2E5FFF2E5EAEBE38EC9DA44B0D501 - 9ACF019ACF019ACF019ACF019ACF019ACF019ACF019ACF019ACFFF00FF019ACF - ABF6FF7EEDFFB88989FFF0E2FFEFDFFFF0E2FFF0E2FFF0E2FFF0E2FFF0E2FEEE - E0FBECDEFAEBDEF6E6D9B8898993F7FF019ACFFF00FFFF00FFFF00FFFF00FFFF - 00FFFF00FF019ACFC7FFFF82F5FFB88989FFEEDFFFECDBFFEEDFFFEEDFFFEEDF - FFEEDFF9E8D9DECCC1D9CABDCFBDB4C8B3ACB88989B5FFFF019ACFFF00FFFF00 - FFFF00FFFF00FFFF00FFFF00FF019ACFA4E0F0A0FDFFB88989FFECDBFFEBD8FF - ECDBFFECDBFFECDBFFECDBF5E2D2C4ABA7C2A8A5BBA39FC2AFA9B88989019ACF - FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF019ACFECFFFFB889 - 89FFEBD8FFEAD5FFEBD8FFEBD8FFEBD8FFEBD8FFEBD8D9C8C5FEFEFDFEF6EFDE - C9C0B88989FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF - FF00FF019ACFB88989FFE9D5FFE8D3FFE9D5FFE9D5FFE9D5FFE9D5FFE9D5C6AD - A9FEF8F2E8D4CACD9999FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF - 00FFFF00FFFF00FFFF00FFFF00FFB88989FFE7D1FFE7D0FFE7D1FFE7D1FFE7D1 - FFE7D1E7CEBFD3BFB9E8D5CCCD9999FF00FFFF00FFFF00FFFF00FFFF00FFFF00 - FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFB88989FFE6CFFFE6CFFF - E6CFFFE6CFFFE6CFFFE6CFD5BBB2E0CCC5CD9999FF00FFFF00FFFF00FFFF00FF - FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFB889 - 89B88989B88989B88989B88989B88989B88989B88989B88989FF00FFFF00FFFF - 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF} - Layout = blGlyphTop - TabOrder = 4 - OnClick = bbSelectedAccountsOperationClick - end end end end object tsPendingOperations: TTabSheet Caption = 'Pending Operations' ImageIndex = 5 - object dgPendingOperations: TDrawGrid + inline FramePendingOperations: TFramePendingOperations Left = 0 - Top = 86 + Top = 0 Width = 857 - Height = 352 + Height = 421 Align = alClient TabOrder = 0 - OnDblClick = MiDecodePayloadClick - end - object pnlPendingOperations: TPanel - Left = 0 - Top = 0 - Width = 857 - Height = 86 - Align = alTop - BevelOuter = bvNone - BorderWidth = 10 - TabOrder = 1 - object Label10: TLabel - Left = 10 - Top = 10 - Width = 837 - Height = 66 - Align = alClient - AutoSize = False - Caption = - 'Here you can see Operations transmited/received from other nodes' + - ' that will be included in next block. There is no guarantee that' + - ' other nodes will include them when mining, so it'#39's important th' + - 'at you mine too to help include Operations to the main BlockChai' + - 'n' - Color = clBtnFace - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = -16 - Font.Name = 'Tahoma' - Font.Style = [] - ParentColor = False - ParentFont = False - WordWrap = True + ExplicitWidth = 857 + ExplicitHeight = 421 + inherited dgPendingOperations: TDrawGrid + Width = 857 + Height = 335 + ExplicitLeft = 0 + ExplicitTop = 86 + ExplicitHeight = 335 + end + inherited pnlPendingOperations: TPanel + Width = 857 + ExplicitLeft = 0 + inherited Label10: TLabel + Width = 837 + end end end end object tsBlockChain: TTabSheet Caption = 'Block Explorer' ImageIndex = 1 - object Panel2: TPanel + inline FrameBlockChainExplorer: TFrameBlockChainExplorer Left = 0 Top = 0 Width = 857 - Height = 41 - Align = alTop - BevelOuter = bvNone + Height = 421 + Align = alClient TabOrder = 0 - object Label9: TLabel - Left = 11 - Top = 10 - Width = 102 - Height = 13 - Caption = 'Filter by blocks range' - Color = clBtnFace - ParentColor = False - end - object lblHashRateBackBlocks: TLabel - Left = 280 - Top = 10 - Width = 104 - Height = 13 - Caption = 'HashRate back blocks' - Color = clBtnFace - ParentColor = False - end - object lblHashRateBackBlocks1: TLabel - Left = 463 - Top = 10 - Width = 24 - Height = 13 - Caption = 'Units' - Color = clBtnFace - ParentColor = False - end - object ebBlockChainBlockStart: TEdit - Left = 125 - Top = 7 - Width = 57 - Height = 21 - TabOrder = 0 - OnExit = ebBlockChainBlockStartExit - OnKeyPress = ebBlockChainBlockStartKeyPress + ExplicitWidth = 296 + ExplicitHeight = 42 + inherited Panel2: TPanel + Width = 857 + ExplicitWidth = 296 end - object ebBlockChainBlockEnd: TEdit - Left = 185 - Top = 7 - Width = 57 - Height = 21 - TabOrder = 1 - OnExit = ebBlockChainBlockStartExit - OnKeyPress = ebBlockChainBlockStartKeyPress + inherited dgBlockChainExplorer: TDrawGrid + Width = 857 + Height = 380 + ExplicitWidth = 857 + ExplicitHeight = 380 end - object ebHashRateBackBlocks: TEdit - Left = 392 - Top = 7 - Width = 56 - Height = 21 - TabOrder = 2 - OnExit = ebHashRateBackBlocksExit - OnKeyPress = ebHashRateBackBlocksKeyPress - end - object cbHashRateUnits: TComboBox - Left = 496 - Top = 7 - Width = 56 - Height = 21 - Style = csDropDownList - ItemIndex = 1 - TabOrder = 3 - Text = 'Mh/s' - OnChange = cbHashRateUnitsClick - OnClick = cbHashRateUnitsClick - Items.Strings = ( - 'Kh/s' - 'Mh/s' - 'Gh/s' - 'Th/s') - end - end - object dgBlockChainExplorer: TDrawGrid - Left = 0 - Top = 41 - Width = 857 - Height = 397 - Align = alClient - TabOrder = 1 end end object tsOperations: TTabSheet Caption = 'Operations Explorer' ImageIndex = 1 - object Panel1: TPanel + inline FrameOperationsExplorer: TFrameOperationsExplorer Left = 0 Top = 0 Width = 857 - Height = 41 - Align = alTop - BevelOuter = bvNone + Height = 421 + Align = alClient TabOrder = 0 - object Label2: TLabel - Left = 11 - Top = 10 - Width = 102 - Height = 13 - Caption = 'Filter by blocks range' - Color = clBtnFace - ParentColor = False - end - object ebFilterOperationsStartBlock: TEdit - Left = 125 - Top = 7 - Width = 57 - Height = 21 - TabOrder = 0 - OnExit = ebFilterOperationsAccountExit - OnKeyPress = ebFilterOperationsAccountKeyPress + ExplicitWidth = 857 + ExplicitHeight = 421 + inherited Panel1: TPanel + Width = 857 + ExplicitWidth = 857 end - object ebFilterOperationsEndBlock: TEdit - Left = 185 - Top = 7 - Width = 57 - Height = 21 - TabOrder = 1 - OnExit = ebFilterOperationsAccountExit - OnKeyPress = ebFilterOperationsAccountKeyPress + inherited dgOperationsExplorer: TDrawGrid + Width = 857 + Height = 380 + ExplicitWidth = 857 + ExplicitHeight = 380 end end - object dgOperationsExplorer: TDrawGrid - Left = 0 - Top = 41 - Width = 857 - Height = 397 - Align = alClient - TabOrder = 1 - end end object tsLogs: TTabSheet Caption = 'Logs' ImageIndex = 2 - object pnlTopLogs: TPanel + inline FrameLogs: TFrameLogs Left = 0 Top = 0 Width = 857 - Height = 41 - Align = alTop - BevelOuter = bvNone + Height = 421 + Align = alClient TabOrder = 0 - object cbShowDebugLogs: TCheckBox - Left = 15 - Top = 10 - Width = 102 - Height = 19 - Caption = 'Show Debug Logs' - TabOrder = 0 + ExplicitWidth = 857 + ExplicitHeight = 421 + inherited memoLogs: TMemo + Width = 857 + Height = 388 + ExplicitWidth = 857 + ExplicitHeight = 388 + end + inherited pnlTopLogs: TPanel + Width = 857 + ExplicitWidth = 857 + inherited ButtonCopyLogToClipboard: TButton + Left = 716 + ExplicitLeft = 716 + end end - end - object memoLogs: TMemo - Left = 0 - Top = 41 - Width = 857 - Height = 397 - Align = alClient - ScrollBars = ssBoth - TabOrder = 1 - WordWrap = False end end object tsNodeStats: TTabSheet Caption = 'Node Stats' ImageIndex = 3 - DesignSize = ( - 857 - 438) - object Label3: TLabel - Left = 15 - Top = 15 - Width = 96 - Height = 13 - Caption = 'Active Connections:' - Color = clBtnFace - ParentColor = False - end - object Label6: TLabel - Left = 15 - Top = 291 - Width = 104 - Height = 13 - Anchors = [akLeft, akRight, akBottom] - Caption = 'Known Node Servers:' - Color = clBtnFace - ParentColor = False - end - object Label7: TLabel - Left = 15 - Top = 187 - Width = 82 - Height = 13 - Anchors = [akLeft, akRight, akBottom] - Caption = 'Blacklisted Nodes' - Color = clBtnFace - ParentColor = False - end - object memoNetConnections: TMemo - Left = 15 - Top = 34 - Width = 830 - Height = 145 - Anchors = [akLeft, akTop, akRight, akBottom] - ReadOnly = True - ScrollBars = ssBoth + inline FrameNodeStats: TFrameNodeStats + Left = 0 + Top = 0 + Width = 857 + Height = 421 + Align = alClient TabOrder = 0 - WordWrap = False - end - object memoNetServers: TMemo - Left = 15 - Top = 310 - Width = 830 - Height = 116 - Anchors = [akLeft, akRight, akBottom] - ReadOnly = True - ScrollBars = ssBoth - TabOrder = 1 - WordWrap = False - end - object memoNetBlackLists: TMemo - Left = 16 - Top = 206 - Width = 829 - Height = 79 - Anchors = [akLeft, akRight, akBottom] - ReadOnly = True - ScrollBars = ssBoth - TabOrder = 2 - WordWrap = False + ExplicitWidth = 857 + ExplicitHeight = 421 + inherited Splitter1: TSplitter + Width = 857 + ExplicitWidth = 857 + end + inherited Splitter2: TSplitter + Top = 264 + Width = 857 + ExplicitTop = 264 + ExplicitWidth = 857 + end + inherited PanelTop: TPanel + Width = 857 + ExplicitWidth = 857 + inherited Panel4: TPanel + Width = 855 + ExplicitWidth = 855 + end + inherited memoNetConnections: TMemo + Width = 855 + ExplicitWidth = 855 + end + end + inherited PanelMiddle: TPanel + Width = 857 + Height = 108 + ExplicitWidth = 857 + ExplicitHeight = 108 + inherited Panel1: TPanel + Width = 855 + ExplicitWidth = 855 + end + inherited memoNetBlackLists: TMemo + Width = 855 + Height = 86 + ExplicitWidth = 855 + ExplicitHeight = 86 + end + end + inherited PanelBottom: TPanel + Top = 267 + Width = 857 + ExplicitTop = 267 + ExplicitWidth = 857 + inherited Panel2: TPanel + Width = 855 + ExplicitWidth = 855 + end + inherited memoNetServers: TMemo + Width = 855 + ExplicitWidth = 855 + end + end end end object tsMessages: TTabSheet Caption = 'Messages' ImageIndex = 6 - DesignSize = ( - 857 - 438) - object Label11: TLabel - Left = 15 - Top = 151 - Width = 51 - Height = 13 - Caption = 'Messages:' - Color = clBtnFace - ParentColor = False - end - object Label12: TLabel - Left = 315 - Top = 11 - Width = 85 - Height = 13 - Caption = 'Message to send:' - Color = clBtnFace - ParentColor = False - end - object Label13: TLabel - Left = 15 - Top = 11 - Width = 109 - Height = 13 - Caption = 'Available Connections:' - Color = clBtnFace - ParentColor = False - end - object Label14: TLabel - Left = 410 - Top = 11 - Width = 361 - Height = 13 - Caption = - '(Messages will be encrypted, so only dest connection will be abl' + - 'e to read it)' - Color = clBtnFace - Font.Charset = DEFAULT_CHARSET - Font.Color = clGrayText - Font.Height = -11 - Font.Name = 'Tahoma' - Font.Style = [] - ParentColor = False - ParentFont = False - end - object lbNetConnections: TListBox - Left = 15 - Top = 30 - Width = 275 - Height = 96 - ItemHeight = 13 - MultiSelect = True - ScrollWidth = 273 + inline FrameMessages: TFrameMessages + Left = 0 + Top = 0 + Width = 857 + Height = 421 + Align = alClient TabOrder = 0 - end - object bbSendAMessage: TButton - Left = 315 - Top = 101 - Width = 525 - Height = 25 - Caption = 'Send a Message' - TabOrder = 1 - OnClick = bbSendAMessageClick - end - object memoMessages: TMemo - Left = 15 - Top = 170 - Width = 821 - Height = 249 - Anchors = [akLeft, akTop, akRight, akBottom] - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = -16 - Font.Name = 'Tahoma' - Font.Style = [] - Lines.Strings = ( - 'dsfa '#195#177'ldsaf '#195#177'lk dasf' - 'dsfklda'#195#177'fs '#195#177'l') - ParentFont = False - ReadOnly = True - ScrollBars = ssBoth - TabOrder = 2 - end - object memoMessageToSend: TMemo - Left = 315 - Top = 30 - Width = 525 - Height = 61 - Lines.Strings = ( - 'memoMessageToSend') - TabOrder = 3 - WantReturns = False + ExplicitWidth = 296 + ExplicitHeight = 42 + inherited Splitter1: TSplitter + Top = 168 + Width = 857 + ExplicitTop = 205 + ExplicitWidth = 857 + end + inherited PanelBottom: TPanel + Top = 171 + Width = 857 + ExplicitTop = -208 + ExplicitWidth = 296 + inherited Panel1: TPanel + Width = 857 + ExplicitWidth = 857 + end + inherited memoMessages: TMemo + Width = 857 + ExplicitWidth = 857 + end + end + inherited PanelTop: TPanel + Width = 857 + Height = 168 + ExplicitWidth = 296 + ExplicitHeight = 168 + inherited Splitter2: TSplitter + Height = 168 + ExplicitHeight = 203 + end + inherited PanelLeft: TPanel + Height = 168 + ExplicitHeight = 168 + inherited lbNetConnections: TListBox + Height = 148 + ExplicitHeight = 148 + end + end + inherited PanelRight: TPanel + Width = 566 + Height = 168 + ExplicitWidth = 5 + ExplicitHeight = 168 + inherited memoMessageToSend: TMemo + Width = 566 + Height = 82 + ExplicitWidth = 566 + ExplicitHeight = 82 + end + inherited Panel6: TPanel + Width = 566 + ExplicitWidth = 566 + end + inherited Panel7: TPanel + Top = 102 + Width = 566 + ExplicitTop = 102 + ExplicitWidth = 566 + DesignSize = ( + 566 + 66) + inherited bbSendAMessage: TButton + Width = 543 + ExplicitWidth = 543 + end + end + end + end end end end object TimerUpdateStatus: TTimer OnTimer = TimerUpdateStatusTimer - Left = 25 - Top = 45 + Left = 801 + Top = 13 end object MainMenu: TMainMenu Left = 165 diff --git a/src/gui-classic/UFRMWallet.pas b/src/gui-classic/UFRMWallet.pas index c39312995..8bd23469f 100644 --- a/src/gui-classic/UFRMWallet.pas +++ b/src/gui-classic/UFRMWallet.pas @@ -36,38 +36,32 @@ interface UCrypto, Buttons, UPoolMining, URPC, UFRMAccountSelect, UConst, UAccountKeyStorage, UBaseTypes, UPCDataTypes, UOrderedList, UFRMRPCCalls, UTxMultiOperation, USettings, UEPasa, - {$IFNDEF FPC}System.Generics.Collections{$ELSE}Generics.Collections{$ENDIF}; - -Const - CM_PC_WalletKeysChanged = WM_USER + 1; - CM_PC_NetConnectionUpdated = WM_USER + 2; + UFRMWalletUserMessages, + UFrameAccountExplorer, + UFramePendingOperations, + UFrameMessages, + UFrameNodeStats, + UFrameLogs, + UFrameOperationsExplorer, + UFrameBlockExplorer, + UFrameInfo, + {$IFNDEF FPC} + System.Generics.Collections + {$ELSE} + Generics.Collections + {$ENDIF}; type - { TFRMWallet } - TFRMWallet = class(TForm) - cbHashRateUnits: TComboBox; - ebHashRateBackBlocks: TEdit; - lblHashRateBackBlocks: TLabel; - lblHashRateBackBlocks1: TLabel; MiRPCCalls: TMenuItem; pnlTop: TPanel; - Image1: TImage; - sbSearchAccount: TSpeedButton; StatusBar: TStatusBar; PageControl: TPageControl; tsMyAccounts: TTabSheet; tsOperations: TTabSheet; TimerUpdateStatus: TTimer; tsLogs: TTabSheet; - pnlTopLogs: TPanel; - cbShowDebugLogs: TCheckBox; - memoLogs: TMemo; - pnlMyAccountsTop: TPanel; - dgAccounts: TDrawGrid; - cbMyPrivateKeys: TComboBox; - Splitter1: TSplitter; MainMenu: TMainMenu; miProject: TMenuItem; miOptions: TMenuItem; @@ -76,88 +70,14 @@ TFRMWallet = class(TForm) miAbout: TMenuItem; miAboutPascalCoin: TMenuItem; miNewOperation: TMenuItem; - Panel1: TPanel; - Label2: TLabel; - ebFilterOperationsStartBlock: TEdit; - ebFilterOperationsEndBlock: TEdit; tsNodeStats: TTabSheet; - memoNetConnections: TMemo; - memoNetServers: TMemo; - memoNetBlackLists: TMemo; - Label3: TLabel; - Label6: TLabel; - Label7: TLabel; - lblCurrentBlockCaption: TLabel; - lblCurrentBlock: TLabel; - lblCurrentBlockTimeCaption: TLabel; - lblCurrentBlockTime: TLabel; - lblOperationsPendingCaption: TLabel; - lblOperationsPending: TLabel; - lblMiningStatusCaption: TLabel; - lblMinersClients: TLabel; - lblCurrentDifficultyCaption: TLabel; - lblCurrentDifficulty: TLabel; - lblTimeAverage: TLabel; - Label4: TLabel; tsBlockChain: TTabSheet; - Panel2: TPanel; - Label9: TLabel; - ebBlockChainBlockStart: TEdit; - ebBlockChainBlockEnd: TEdit; - Label8: TLabel; - lblNodeStatus: TLabel; tsPendingOperations: TTabSheet; - dgPendingOperations: TDrawGrid; - pnlPendingOperations: TPanel; - Label10: TLabel; - cbExploreMyAccounts: TCheckBox; N1: TMenuItem; MiClose: TMenuItem; MiDecodePayload: TMenuItem; - Label5: TLabel; - lblCurrentAccounts: TLabel; - lblTimeAverageAux: TLabel; tsMessages: TTabSheet; - lbNetConnections: TListBox; - bbSendAMessage: TButton; - Label11: TLabel; - memoMessages: TMemo; - memoMessageToSend: TMemo; - Label12: TLabel; - Label13: TLabel; - Label14: TLabel; - Label16: TLabel; - lblBlocksFound: TLabel; - pnlAccounts: TPanel; - pnlAccountsInfo: TPanel; - Label17: TLabel; - Label19: TLabel; - lblAccountsCount: TLabel; - lblAccountsBalance: TLabel; - lblReceivedMessages: TLabel; - lblBuild: TLabel; - ebFindAccountNumber: TEdit; - Label18: TLabel; IPnodes1: TMenuItem; - bbChangeKeyName: TBitBtn; - pcAccountsOptions: TPageControl; - tsAccountOperations: TTabSheet; - dgAccountOperations: TDrawGrid; - tsMultiSelectAccounts: TTabSheet; - dgSelectedAccounts: TDrawGrid; - pnlSelectedAccountsTop: TPanel; - pnlSelectedAccountsBottom: TPanel; - pnlSelectedAccountsLeft: TPanel; - sbSelectedAccountsAdd: TSpeedButton; - sbSelectedAccountsAddAll: TSpeedButton; - sbSelectedAccountsDel: TSpeedButton; - sbSelectedAccountsDelAll: TSpeedButton; - Label20: TLabel; - lblSelectedAccountsCount: TLabel; - Label22: TLabel; - lblSelectedAccountsBalance: TLabel; - bbSelectedAccountsOperation: TBitBtn; - Label15: TLabel; MiOperations: TMenuItem; MiAddaccounttoSelected: TMenuItem; MiRemoveaccountfromselected: TMenuItem; @@ -167,91 +87,51 @@ TFRMWallet = class(TForm) MiFindnextaccountwithhighbalance: TMenuItem; MiFindpreviousaccountwithhighbalance: TMenuItem; MiFindaccount: TMenuItem; - cbFilterAccounts: TCheckBox; - ebFilterAccountByBalanceMin: TEdit; - ebFilterAccountByBalanceMax: TEdit; - bbAccountsRefresh: TBitBtn; - dgBlockChainExplorer: TDrawGrid; - dgOperationsExplorer: TDrawGrid; MiFindOperationbyOpHash: TMenuItem; MiAccountInformation: TMenuItem; MiOperationsExplorer: TMenuItem; - procedure cbHashRateUnitsClick(Sender: TObject); - procedure ebHashRateBackBlocksExit(Sender: TObject); - procedure ebHashRateBackBlocksKeyPress(Sender: TObject; var Key: char); + FrameAccountExplorer: TFrameAccountExplorer; + FramePendingOperations: TFramePendingOperations; + FrameBlockChainExplorer: TFrameBlockChainExplorer; + FrameOperationsExplorer: TFrameOperationsExplorer; + FrameMessages: TFrameMessages; + FrameInfo: TFrameInfo; + FrameNodeStats: TFrameNodeStats; + FrameLogs: TFrameLogs; + procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); + procedure MiOperationsExplorerClick(Sender: TObject); procedure MiRPCCallsClick(Sender: TObject); - procedure sbSearchAccountClick(Sender: TObject); procedure TimerUpdateStatusTimer(Sender: TObject); - procedure cbMyPrivateKeysChange(Sender: TObject); - procedure dgAccountsClick(Sender: TObject); procedure miOptionsClick(Sender: TObject); procedure miAboutPascalCoinClick(Sender: TObject); procedure miNewOperationClick(Sender: TObject); procedure miPrivatekeysClick(Sender: TObject); - procedure dgAccountsColumnMoved(Sender: TObject; FromIndex, - ToIndex: Integer); - procedure dgAccountsFixedCellClick(Sender: TObject; ACol, ARow: Integer); procedure PageControlChange(Sender: TObject); - procedure ebFilterOperationsAccountExit(Sender: TObject); - procedure ebFilterOperationsAccountKeyPress(Sender: TObject; var Key: Char); - procedure ebBlockChainBlockStartExit(Sender: TObject); - procedure ebBlockChainBlockStartKeyPress(Sender: TObject; var Key: Char); - procedure cbExploreMyAccountsClick(Sender: TObject); procedure MiCloseClick(Sender: TObject); procedure MiDecodePayloadClick(Sender: TObject); - procedure bbSendAMessageClick(Sender: TObject); procedure lblReceivedMessagesClick(Sender: TObject); - procedure ebFindAccountNumberChange(Sender: TObject); - procedure ebFindAccountNumberExit(Sender: TObject); procedure IPnodes1Click(Sender: TObject); - procedure bbChangeKeyNameClick(Sender: TObject); - procedure sbSelectedAccountsAddClick(Sender: TObject); - procedure sbSelectedAccountsAddAllClick(Sender: TObject); - procedure sbSelectedAccountsDelClick(Sender: TObject); - procedure sbSelectedAccountsDelAllClick(Sender: TObject); - procedure bbSelectedAccountsOperationClick(Sender: TObject); procedure MiAddaccounttoSelectedClick(Sender: TObject); procedure MiRemoveaccountfromselectedClick(Sender: TObject); procedure MiMultiaccountoperationClick(Sender: TObject); procedure MiFindnextaccountwithhighbalanceClick(Sender: TObject); procedure MiFindpreviousaccountwithhighbalanceClick(Sender: TObject); procedure MiFindaccountClick(Sender: TObject); - procedure bbAccountsRefreshClick(Sender: TObject); - procedure ebFilterAccountByBalanceMinExit(Sender: TObject); - procedure ebFilterAccountByBalanceMinKeyPress(Sender: TObject; - var Key: Char); - procedure cbFilterAccountsClick(Sender: TObject); procedure MiFindOperationbyOpHashClick(Sender: TObject); procedure MiAccountInformationClick(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); - procedure Test_ShowDiagnosticTool(Sender: TObject); procedure miAskForAccountClick(Sender: TObject); + private FLastNodesCacheUpdatedTS : TDateTime; FBackgroundPanel : TPanel; FBackgroundLabel : TLabel; - FMinersBlocksFound: Integer; - procedure SetMinersBlocksFound(const Value: Integer); - Procedure CheckIsReady; Procedure FinishedLoadingApp; - Procedure FillAccountInformation(Const Strings : TStrings; Const AccountNumber : Cardinal); - Procedure FillOperationInformation(Const Strings : TStrings; Const OperationResume : TOperationResume); +// Procedure FillAccountInformation(Const Strings : TStrings; Const AccountNumber : Cardinal); Procedure InitMacOSMenu; - Procedure InitMenuForTesting; - {$IFDEF TESTNET} - Procedure Test_RandomOperations(Sender: TObject); - {$IFDEF TESTING_NO_POW_CHECK} - Procedure Test_CreateABlock(Sender: TObject); - {$ENDIF} - Procedure Test_ConnectDisconnect(Sender: TObject); - {$ENDIF} - Procedure Test_ShowPublicKeys(Sender: TObject); - Procedure Test_ShowOperationsInMemory(Sender: TObject); - Procedure Test_FindAccountsForPrivateBuyOrSwapToMe(Sender : TObject); - procedure OnAccountsGridUpdatedData(Sender : TObject); protected { Private declarations } FNode : TNode; @@ -267,46 +147,48 @@ TFRMWallet = class(TForm) FBlockChainGrid : TBlockChainGrid; FMinerPrivateKeyType : TMinerPrivateKeyType; FUpdating : Boolean; - FMessagesUnreadCount : Integer; - FMinAccountBalance : Int64; - FMaxAccountBalance : Int64; FPoolMiningServer : TPoolMiningServer; FRPCServer : TRPCServer; FMustProcessWalletChanged : Boolean; - FMustProcessNetConnectionUpdated : Boolean; FThreadActivate : TObject; - FLastAccountsGridInvalidateTC : TTickCount; + Procedure OnNewAccount(Sender : TObject); Procedure OnReceivedHelloMessage(Sender : TObject); Procedure OnNetStatisticsChanged(Sender : TObject); - procedure OnNewLog(logtype : TLogType; Time : TDateTime; ThreadID : TThreadID; Const sender, logtext : String); procedure OnWalletChanged(Sender : TObject); - procedure OnNetConnectionsUpdated(Sender : TObject); - procedure OnNetNodeServersUpdated(Sender : TObject); - procedure OnNetBlackListUpdated(Sender : TObject); - Procedure OnNodeMessageEvent(NetConnection : TNetConnection; MessageData : String); Procedure OnNodeKeysActivity(Sender : TObject); - Procedure OnSelectedAccountsGridUpdated(Sender : TObject); Procedure OnMiningServerNewBlockFound(Sender : TObject); Procedure UpdateConnectionStatus; - Procedure UpdateAccounts(RefreshData : Boolean); - Procedure UpdateBlockChainState; - Procedure UpdatePrivateKeys; - Procedure UpdateOperations; Procedure UpdateConfigChanged(Sender:TObject); - Procedure UpdateNodeStatus; - Procedure UpdateAvailableConnections; procedure Activate; override; Function ForceMining : Boolean; virtual; Function GetAccountKeyForMiner : TAccountKey; Procedure DoUpdateAccounts; - Function DoUpdateAccountsFilter : Boolean; procedure CM_WalletChanged(var Msg: TMessage); message CM_PC_WalletKeysChanged; - procedure CM_NetConnectionUpdated(var Msg: TMessage); message CM_PC_NetConnectionUpdated; +// procedure CM_NetConnectionUpdated(var Msg: TMessage); message CM_PC_NetConnectionUpdated; // moved to UFrameNodeStats, Skybuck: not sure yet if Frames can received messages public + Procedure CheckIsReady; + + Procedure UpdateOperations; + + Property BackgroundLabel : TLabel read FBackgroundLabel; + { Public declarations } + Property Node : TNode read FNode; + Property WalletKeys : TWalletKeysExt read FWalletKeys; - Property MinersBlocksFound : Integer read FMinersBlocksFound write SetMinersBlocksFound; + + Property NodeNotifyEvents : TNodeNotifyEvents read FNodeNotifyEvents; + + Property Updating : boolean read FUpdating write FUpdating; + + property OperationsExplorerGrid : TOperationsGrid read FOperationsExplorerGrid; + Property BlockChainGrid : TBlockChainGrid read FBlockChainGrid; + +// Property SelectedAccountsGrid : TAccountsGrid read FSelectedAccountsGrid; + + Property PoolMiningServer : TPoolMiningServer read FPoolMiningServer; + end; var @@ -325,7 +207,7 @@ implementation UOpenSSL, {$ENDIF} UTime, UFileStorage, - UThread, UOpTransaction, UFRMPascalCoinWalletConfig, + UThread, UOpTransaction, UFRMWalletConfig, UFRMOperationsExplorer, {$IFDEF TESTNET} UFRMRandomOperations, @@ -335,10 +217,10 @@ implementation UFRMAskForAccount, UAbstractBTree, UEPasaDecoder, UFRMAbout, UFRMOperation, UFRMWalletKeys, UFRMPayloadDecoder, UFRMNodesIp, UFRMMemoText, - UCommon, UPCOrderedLists; + UCommon, UPCOrderedLists, + UFRMWalletInformation; Type - { TThreadActivate } TThreadActivate = Class(TPCThread) @@ -371,7 +253,7 @@ procedure TThreadActivate.ThreadSafeNotify; if Assigned(FRMWallet.FBackgroundLabel) then begin FRMWallet.FBackgroundLabel.Caption:=FLastMsg; end; - end else FRMWallet.UpdateNodeStatus; + end else FRMWallet.FrameInfo.UpdateNodeStatus; end; procedure TThreadActivate.BCExecute; @@ -416,6 +298,11 @@ procedure TThreadActivate.BCExecute; { TFRMWallet } +procedure TFRMWallet.lblReceivedMessagesClick(Sender: TObject); +begin + PageControl.ActivePage := tsMessages; +end; + procedure TFRMWallet.Activate; Var ips : AnsiString; nsarr : TNodeServerAddressArray; @@ -455,9 +342,9 @@ procedure TFRMWallet.Activate; TFileStorage(FNode.Bank.Storage).DatabaseFolder := TNode.GetPascalCoinDataFolder+PathDelim+'Data'; TFileStorage(FNode.Bank.Storage).Initialize; // Init Grid - FSelectedAccountsGrid.Node := FNode; + FrameAccountExplorer.SelectedAccountsGrid.Node := FNode; FWalletKeys.OnChanged.Add( OnWalletChanged ); - FAccountsGrid.Node := FNode; + FrameAccountExplorer.AccountsGrid.Node := FNode; FOperationsAccountGrid.Node := FNode; FBlockChainGrid.HashRateAverageBlocksCount := TSettings.HashRateAvgBlocksCount; i := Integer(TSettings.ShowHashRateAs); @@ -468,7 +355,7 @@ procedure TFRMWallet.Activate; TThreadActivate(FThreadActivate).FreeOnTerminate := true; TThreadActivate(FThreadActivate).Suspended := False; UpdateConfigChanged(Self); - UpdateNodeStatus; + FrameInfo.UpdateNodeStatus; TPCTNetDataExtraMessages.InitNetDataExtraMessages(FNode,TNetData.NetData,FWalletKeys); Except On E:Exception do begin @@ -477,8 +364,8 @@ procedure TFRMWallet.Activate; Halt; end; end; - UpdatePrivateKeys; - UpdateAccounts(false); + FrameAccountExplorer.UpdatePrivateKeys; + FrameAccountExplorer.UpdateAccounts(false); if TSettings.FirstTime then begin TSettings.FirstTime := false; miAboutPascalCoinClick(Nil); @@ -486,556 +373,6 @@ procedure TFRMWallet.Activate; PageControlChange(Nil); end; -procedure TFRMWallet.bbAccountsRefreshClick(Sender: TObject); -begin - UpdateAccounts(true); -end; - -procedure TFRMWallet.bbChangeKeyNameClick(Sender: TObject); -var i : Integer; - name : String; -begin - if (cbMyPrivateKeys.ItemIndex<0) then exit; - i := PtrInt(cbMyPrivateKeys.Items.Objects[cbMyPrivateKeys.ItemIndex]); - if (i<0) Or (i>=FWalletKeys.Count) then raise Exception.Create('Must select a Key'); - name := FWalletKeys.Key[i].Name; - if InputQuery('Change Key name','Input new name',name) then begin - FWalletKeys.SetName(i,name); - end; - UpdatePrivateKeys; -end; - -procedure TFRMWallet.bbSelectedAccountsOperationClick(Sender: TObject); -var l : TOrderedCardinalList; -begin - CheckIsReady; - if FSelectedAccountsGrid.AccountsCount<=0 then raise Exception.Create('Must select at least 1 account'); - With TFRMOperation.Create(Self) do - Try - l := FSelectedAccountsGrid.LockAccountsList; - try - SenderAccounts.CopyFrom(l); - finally - FSelectedAccountsGrid.UnlockAccountsList; - end; - DefaultFee := TSettings.DefaultFee; - WalletKeys := FWalletKeys; - ShowModal; - Finally - Free; - End; -end; - -procedure TFRMWallet.bbSendAMessageClick(Sender: TObject); -Var basem,m : String; - them, errors : String; - i,n : Integer; - nc : TNetConnection; -begin - CheckIsReady; - if (lbNetConnections.SelCount<=0) Or (lbNetConnections.ItemIndex<0) then raise Exception.Create('Select at least one connection'); - if lbNetConnections.SelCount<=0 then n := 1 - else n := lbNetConnections.SelCount; - - basem := memoMessageToSend.Lines.Text; - m := ''; - // Clear non valid characters: - for i := Low(basem) to High(basem) do begin - if basem[i] in [#32..#127] then m := m + basem[i] - else m:=m+'.'; - end; - - if trim(m)='' then raise Exception.Create('No message'); - - if Application.MessageBox(PChaR('Send this message to '+inttostr(n)+' nodes?'+#10+ - 'NOTE: Sending unauthorized messages will be considered spam and you will be banned'+#10+ - #10+ - 'Message: '+#10+ - m),PChar(Application.Title),MB_ICONQUESTION+MB_YESNO+MB_DEFBUTTON1)<>IdYes then exit; - them := m; - if n>1 then begin - for i := 0 to lbNetConnections.Items.Count - 1 do begin - if lbNetConnections.Selected[i] then begin - nc := TNetConnection(lbNetconnections.Items.Objects[i]); - if TNetData.NetData.ConnectionExistsAndActive(nc) then begin - FNode.SendNodeMessage(nc,m,errors); - memoMessages.Lines.Add(DateTimeToStr(now)+' Sent to '+nc.ClientRemoteAddr+' > '+m); - end; - end; - end; - end else begin - nc := TNetConnection(lbNetconnections.Items.Objects[lbNetconnections.ItemIndex]); - if TNetData.NetData.ConnectionExistsAndActive(nc) then begin - FNode.SendNodeMessage(nc,m,errors); - memoMessages.Lines.Add(DateTimeToStr(now)+' Sent to '+nc.ClientRemoteAddr+' > '+m); - end; - end; - - Application.MessageBox(PChaR('Message sent to '+inttostr(n)+' nodes'+#10+ - 'Message: '+#10+m),PChar(Application.Title),MB_ICONINFORMATION+MB_OK); -end; - -procedure TFRMWallet.cbExploreMyAccountsClick(Sender: TObject); -begin - cbMyPrivateKeys.Enabled := cbExploreMyAccounts.Checked; - UpdateAccounts(true); - UpdateOperations; -end; - -procedure TFRMWallet.cbFilterAccountsClick(Sender: TObject); -begin - If not DoUpdateAccountsFilter then UpdateAccounts(true); -end; - -procedure TFRMWallet.cbMyPrivateKeysChange(Sender: TObject); -begin - UpdateAccounts(true); -end; - -procedure TFRMWallet.CheckIsReady; -Var isready : String; -begin - if Not Assigned(FNode) then Abort; - - if Not FNode.IsReady(isready) then begin - Raise Exception.Create('You cannot do this operation now:'+#10+#10+isready); - end; -end; - -procedure TFRMWallet.CM_NetConnectionUpdated(var Msg: TMessage); -Const CT_BooleanToString : Array[Boolean] of String = ('False','True'); -Var i : integer; - NC : TNetConnection; - l : TList; - sClientApp, sLastConnTime : String; - strings, sNSC, sRS, sDisc : TStrings; - hh,nn,ss,ms : Word; -begin - Try - if Not TNetData.NetData.NetConnections.TryLockList(100,l) then exit; - try - strings := memoNetConnections.Lines; - sNSC := TStringList.Create; - sRS := TStringList.Create; - sDisc := TStringList.Create; - strings.BeginUpdate; - Try - for i := 0 to l.Count - 1 do begin - NC := l[i]; - If NC.Client.BytesReceived>0 then begin - sClientApp := '['+IntToStr(NC.NetProtocolVersion.protocol_version)+'-'+IntToStr(NC.NetProtocolVersion.protocol_available)+'] '+NC.ClientAppVersion; - end else begin - sClientApp := '(no data)'; - end; - - if NC.Connected then begin - if NC.Client.LastCommunicationTime>1000 then begin - DecodeTime(now - NC.Client.LastCommunicationTime,hh,nn,ss,ms); - if (hh=0) and (nn=0) And (ss<10) then begin - sLastConnTime := ' - Last comunication <10 sec.'; - end else begin - sLastConnTime := Format(' - Last comunication %.2dm%.2ds',[(hh*60)+nn,ss]); - end; - end else begin - sLastConnTime := ''; - end; - if NC is TNetServerClient then begin - sNSC.Add(Format('Client: IP:%s Block:%d Sent/Received:%d/%d Bytes - %s - Time offset %d - Active since %s %s', - [NC.ClientRemoteAddr,NC.RemoteOperationBlock.block,NC.Client.BytesSent,NC.Client.BytesReceived,sClientApp,NC.TimestampDiff,DateTimeElapsedTime(NC.CreatedTime),sLastConnTime])); - end else begin - if NC.IsMyselfServer then sNSC.Add(Format('MySelf IP:%s Sent/Received:%d/%d Bytes - %s - Time offset %d - Active since %s %s', - [NC.ClientRemoteAddr,NC.Client.BytesSent,NC.Client.BytesReceived,sClientApp,NC.TimestampDiff,DateTimeElapsedTime(NC.CreatedTime),sLastConnTime])) - else begin - sRS.Add(Format('Remote Server: IP:%s Block:%d Sent/Received:%d/%d Bytes - %s - Time offset %d - Active since %s %s', - [NC.ClientRemoteAddr,NC.RemoteOperationBlock.block,NC.Client.BytesSent,NC.Client.BytesReceived,sClientApp,NC.TimestampDiff,DateTimeElapsedTime(NC.CreatedTime),sLastConnTime])); - end; - end; - end else begin - if NC is TNetServerClient then begin - sDisc.Add(Format('Disconnected client: IP:%s - %s',[NC.ClientRemoteAddr,sClientApp])); - end else if NC.IsMyselfServer then begin - sDisc.Add(Format('Disconnected MySelf IP:%s - %s',[NC.ClientRemoteAddr,sClientApp])); - end else begin - sDisc.Add(Format('Disconnected Remote Server: IP:%s %s - %s',[NC.ClientRemoteAddr,CT_BooleanToString[NC.Connected],sClientApp])); - end; - end; - end; - strings.Clear; - strings.Add(Format('Connections Updated %s Clients:%d Servers:%d (valid servers:%d)',[DateTimeToStr(now),sNSC.Count,sRS.Count,TNetData.NetData.NetStatistics.ServersConnectionsWithResponse])); - strings.AddStrings(sRS); - strings.AddStrings(sNSC); - if sDisc.Count>0 then begin - strings.Add(''); - strings.Add('Disconnected connections: '+Inttostr(sDisc.Count)); - strings.AddStrings(sDisc); - end; - Finally - strings.EndUpdate; - sNSC.Free; - sRS.Free; - sDisc.Free; - End; - //CheckMining; - finally - TNetData.NetData.NetConnections.UnlockList; - end; - Finally - FMustProcessNetConnectionUpdated := false; - End; -end; - -procedure TFRMWallet.CM_WalletChanged(var Msg: TMessage); -begin - UpdatePrivateKeys; - FMustProcessWalletChanged := false; -end; - -procedure TFRMWallet.dgAccountsClick(Sender: TObject); -begin - UpdateOperations; -end; - -procedure TFRMWallet.dgAccountsColumnMoved(Sender: TObject; FromIndex, ToIndex: Integer); -begin - TSettings.Save; -end; - -procedure TFRMWallet.dgAccountsFixedCellClick(Sender: TObject; ACol, - ARow: Integer); -begin - TSettings.Save; -end; - -procedure TFRMWallet.DoUpdateAccounts; -begin - UpdateAccounts(true); -end; - -function TFRMWallet.DoUpdateAccountsFilter: Boolean; -Var m,bmin,bmax:Int64; - doupd : Boolean; -begin - if FUpdating then exit; - FUpdating := true; - Try - If Not TAccountComp.TxtToMoney(ebFilterAccountByBalanceMin.Text,bmin) then bmin := 0; - If not TAccountComp.TxtToMoney(ebFilterAccountByBalanceMax.Text,bmax) then bmax := CT_MaxWalletAmount; - if (bmaxbmax then bmin := 0; - doupd := (bmin<>FMinAccountBalance) Or (bmax<>FMaxAccountBalance); - if bmin>0 then - ebFilterAccountByBalanceMin.Text:=TAccountComp.FormatMoney(bmin) - else ebFilterAccountByBalanceMin.Text := ''; - if bmax=0 then ebBlockChainBlockStart.Text := Inttostr(FBlockChainGrid.BlockStart) else ebBlockChainBlockStart.Text := ''; - if FBlockChainGrid.BlockEnd>=0 then ebBlockChainBlockEnd.Text := Inttostr(FBlockChainGrid.BlockEnd) else ebBlockChainBlockEnd.Text := ''; - Finally - FUpdating := false; - End; -end; - -procedure TFRMWallet.ebBlockChainBlockStartKeyPress(Sender: TObject; - var Key: Char); -begin - if key=#13 then ebBlockChainBlockStartExit(Nil); -end; - -procedure TFRMWallet.ebFilterAccountByBalanceMinExit(Sender: TObject); -begin - DoUpdateAccountsFilter; -end; - -procedure TFRMWallet.ebFilterAccountByBalanceMinKeyPress(Sender: TObject; - var Key: Char); -begin - if key=#13 then DoUpdateAccountsFilter; -end; - -procedure TFRMWallet.ebFilterOperationsAccountExit(Sender: TObject); -Var bstart,bend : Int64; -begin - If FUpdating then exit; - FUpdating := True; - Try - bstart := StrToInt64Def(ebFilterOperationsStartBlock.Text,-1); - if bstart>=0 then ebFilterOperationsStartBlock.Text := Inttostr(bstart) else ebFilterOperationsStartBlock.Text := ''; - bend := StrToInt64Def(ebFilterOperationsEndBlock.Text,-1); - if bend>=0 then ebFilterOperationsEndBlock.Text := Inttostr(bend) else ebFilterOperationsEndBlock.Text := ''; - FOperationsExplorerGrid.SetBlocks(bstart,bend); - Finally - FUpdating := false; - End; -end; - -procedure TFRMWallet.ebFilterOperationsAccountKeyPress(Sender: TObject; - var Key: Char); -begin - if key=#13 then ebFilterOperationsAccountExit(Nil); -end; - -procedure TFRMWallet.ebFindAccountNumberChange(Sender: TObject); -Var an : Cardinal; - LAccountNameRawValue : TRawBytes; - LErrors : String; - LAccNames : TOrderedRawList; -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 - LAccountNameRawValue.FromString(ebFindAccountNumber.Text); - LAccNames := TOrderedRawList.Create; - Try - if FNode.Bank.SafeBox.FindAccountsStartingByName(LAccountNameRawValue,LAccNames,1)>0 then begin - an := LAccNames.GetTag(0); - 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; - Finally - LAccNames.Free; - End; - end; -end; - -procedure TFRMWallet.ebFindAccountNumberExit(Sender: TObject); -begin - ebFindAccountNumber.Text := ''; -end; - -procedure TFRMWallet.FinishedLoadingApp; -var LLockedMempool : TPCOperationsComp; - LFoundAccounts, i, LOnSafebox,LOnMempool : Integer; - Lpubkeys : TList; -begin - FNodeNotifyEvents.Node := FNode; - // Init - TNetData.NetData.OnReceivedHelloMessage := OnReceivedHelloMessage; - TNetData.NetData.OnStatisticsChanged := OnNetStatisticsChanged; - TNetData.NetData.OnNetConnectionsUpdated := onNetConnectionsUpdated; - TNetData.NetData.OnNodeServersUpdated := OnNetNodeServersUpdated; - TNetData.NetData.OnBlackListUpdated := OnNetBlackListUpdated; - // - TimerUpdateStatus.Interval := 1000; - TimerUpdateStatus.Enabled := true; - // - FPoolMiningServer := TPoolMiningServer.Create; - FPoolMiningServer.Port := TSettings.JsonRpcMinerServerPort; - FPoolMiningServer.MinerAccountKey := GetAccountKeyForMiner; - FPoolMiningServer.MinerPayload := TEncoding.ANSI.GetBytes(TSettings.MinerName); - LLockedMempool := FNode.LockMempoolWrite; - try - LLockedMempool.AccountKey := GetAccountKeyForMiner; - finally - FNode.UnlockMempoolWrite; - end; - FPoolMiningServer.Active := TSettings.JsonRpcMinerServerActive; - FPoolMiningServer.OnMiningServerNewBlockFound := OnMiningServerNewBlockFound; - FreeAndNil(FBackgroundLabel); - FreeAndNil(FBackgroundPanel); - - PageControl.Visible:=True; - PageControl.Enabled:=True; - - UpdatePrivateKeys; - // - LFoundAccounts := 0; - FNode.Bank.SafeBox.StartThreadSafe; - try - Lpubkeys := TList.Create; - Try - for i := 0 to FWalletKeys.Count-1 do begin - if (FWalletKeys.Key[i].HasPrivateKey) then begin - Lpubkeys.Add(FWalletKeys.Key[i].AccountKey); - end; - end; - if (Lpubkeys.Count>0) then begin - LFoundAccounts := FNode.GetAccountsAvailableByPublicKey(Lpubkeys,LOnSafebox,LOnMempool); - end else LFoundAccounts := 0; - Finally - Lpubkeys.Free; - End; - finally - FNode.Bank.SafeBox.EndThreadSave; - end; - if LFoundAccounts<1 then begin - // Will only ask if no accounts - TFRMAskForAccount.AskForAccount(Self,FNode,TNetData.NetData,FWalletKeys,GetAccountKeyForMiner); - end; -end; - -procedure TFRMWallet.FillAccountInformation(const Strings: TStrings; - const AccountNumber: Cardinal); -Var account : TAccount; - s : String; - LjsonObj : TPCJSONObject; -begin - if AccountNumber<0 then exit; - account := FNode.GetMempoolAccount(AccountNumber); - if Length(account.name)>0 then s:='Name: '+TEncoding.ANSI.GetString(account.name) - else s:=''; - Strings.Add(Format('Account: %s %s Type:%d',[TAccountComp.AccountNumberToAccountTxtNumber(AccountNumber),s,account.account_type])); - Strings.Add(''); - Strings.Add(Format('Current balance: %s',[TAccountComp.FormatMoney(account.balance)])); - Strings.Add(''); - Strings.Add(Format('Updated on block: %d (%d blocks ago)',[account.GetLastUpdatedBlock,FNode.Bank.BlocksCount-account.GetLastUpdatedBlock])); - Strings.Add(Format('Updated on block as active mode: %d (%d blocks ago)',[account.updated_on_block_active_mode,FNode.Bank.BlocksCount-account.updated_on_block_active_mode])); - Strings.Add(Format('Public key type: %s',[TAccountComp.GetECInfoTxt(account.accountInfo.accountKey.EC_OpenSSL_NID)])); - Strings.Add(Format('Base58 Public key: %s',[TAccountComp.AccountPublicKeyExport(account.accountInfo.accountKey)])); - if Length(account.account_data)>0 then - Strings.Add(Format('Account Data: %s',[account.account_data.ToHexaString])) - else Strings.Add(Format('Account Data: (No data)',[])); - Strings.Add(Format('Account Seal: %s',[account.account_seal.ToHexaString])); - if TAccountComp.IsAccountForSale(account.accountInfo) then begin - Strings.Add(''); - Strings.Add('** Account is for sale: **'); - Strings.Add(Format('Price: %s',[TAccountComp.FormatMoney(account.accountInfo.price)])); - Strings.Add(Format('Seller account (where to pay): %s',[TAccountComp.AccountNumberToAccountTxtNumber(account.accountInfo.account_to_pay)])); - if TAccountComp.IsAccountForPrivateSale(account.accountInfo) then begin - Strings.Add(''); - Strings.Add('** Private sale **'); - Strings.Add(Format('New Base58 Public key: %s',[TAccountComp.AccountPublicKeyExport(account.accountInfo.new_publicKey)])); - Strings.Add(''); - if TAccountComp.IsAccountLocked(account.accountInfo,FNode.Bank.BlocksCount) then begin - Strings.Add(Format('PURCHASE IS SECURE UNTIL BLOCK %d (current %d, remains %d)', - [account.accountInfo.locked_until_block,FNode.Bank.BlocksCount,account.accountInfo.locked_until_block-FNode.Bank.BlocksCount])); - end else begin - Strings.Add(Format('PURCHASE IS NOT SECURE (Expired on block %d, current %d)', - [account.accountInfo.locked_until_block,FNode.Bank.BlocksCount])); - end; - end; - end else if TAccountComp.IsAccountForSwap(account.accountInfo) then begin - Strings.Add(''); - if TAccountComp.IsAccountForAccountSwap(account.accountInfo) then begin - Strings.Add('** Account is for Atomic Account Swap: **'); - Strings.Add(Format('New Base58 Public key: %s',[TAccountComp.AccountPublicKeyExport(account.accountInfo.new_publicKey)])); - end else if TAccountComp.IsAccountForCoinSwap(account.accountInfo) then begin - Strings.Add('** Account is for Atomic Coin Swap: **'); - Strings.Add(Format('Amount to swap: %s',[TAccountComp.FormatMoney(account.accountInfo.price)])); - Strings.Add(Format('Counterparty account: %s',[TAccountComp.AccountNumberToAccountTxtNumber(account.accountInfo.account_to_pay)])); - end; - Strings.Add(Format('Public secret to find: %s',[account.accountInfo.hashed_secret.ToHexaString])); - Strings.Add(''); - if TAccountComp.IsAccountLocked(account.accountInfo,FNode.Bank.BlocksCount) then begin - Strings.Add(Format('SWAP IS SECURE UNTIL BLOCK %d (current %d, remains %d)', - [account.accountInfo.locked_until_block,FNode.Bank.BlocksCount,account.accountInfo.locked_until_block-FNode.Bank.BlocksCount])); - end else begin - Strings.Add(Format('SWAP IS NOT SECURE (Expired on block %d, current %d)', - [account.accountInfo.locked_until_block,FNode.Bank.BlocksCount])); - end; - end; - LjsonObj := TPCJSONObject.Create; - Try - TPascalCoinJSONComp.FillAccountObject(account,LjsonObj); - Strings.Add('ACCOUNT JSON:'); - Strings.Add(LjsonObj.ToJSON(False)); - Finally - LjsonObj.Free; - end; - -end; - -procedure TFRMWallet.FillOperationInformation(const Strings: TStrings; - const OperationResume: TOperationResume); -var i : Integer; - jsonObj : TPCJSONObject; - LEPASA : TEPasa; -begin - If (not OperationResume.valid) then exit; - If OperationResume.Block=0) then begin - Strings.Add(Format('Block: %d/%d',[OperationResume.Block,OperationResume.NOpInsideBlock])) - end else begin - Strings.Add(Format('Block: %d',[OperationResume.Block])) - end - else Strings.Add('** Pending operation not included on blockchain **'); - Strings.Add(Format('%s',[OperationResume.OperationTxt])); - If (OperationResume.isMultiOperation) then begin - Strings.Add('Multioperation:'); - For i := 0 to High(OperationResume.Senders) do begin - Strings.Add(Format(' Sender (%d/%d): %s %s PASC Payload(%d):%s',[i+1,length(OperationResume.Senders),TAccountComp.AccountNumberToAccountTxtNumber(OperationResume.Senders[i].Account),TAccountComp.FormatMoney(OperationResume.Senders[i].Amount),OperationResume.Senders[i].Payload.payload_type,OperationResume.Senders[i].Payload.payload_raw.ToHexaString])); - end; - For i := 0 to High(OperationResume.Receivers) do begin - Strings.Add(Format(' Receiver (%d/%d): %s %s PASC Payload(%d):%s',[i+1,length(OperationResume.Receivers),TAccountComp.AccountNumberToAccountTxtNumber(OperationResume.Receivers[i].Account),TAccountComp.FormatMoney(OperationResume.Receivers[i].Amount),OperationResume.Receivers[i].Payload.payload_type,OperationResume.Receivers[i].Payload.payload_raw.ToHexaString])); - end; - For i := 0 to High(OperationResume.Changers) do begin - Strings.Add(Format(' Change info (%d/%d): %s [%s]',[i+1,length(OperationResume.Changers),TAccountComp.AccountNumberToAccountTxtNumber(OperationResume.Changers[i].Account),TOpMultiOperation.OpChangeAccountInfoTypesToText(OperationResume.Changers[i].Changes_type)])); - end; - - end; - Strings.Add(Format('OpType:%d Subtype:%d',[OperationResume.OpType,OperationResume.OpSubtype])); - Strings.Add(Format('Operation Hash (ophash): %s',[TCrypto.ToHexaString(OperationResume.OperationHash)])); - If (Length(OperationResume.OperationHash_OLD)>0) then begin - Strings.Add(Format('Old Operation Hash (old_ophash): %s',[TCrypto.ToHexaString(OperationResume.OperationHash_OLD)])); - end; - if TEPasaDecoder.TryDecodeEPASA(OperationResume.DestAccount,OperationResume.OriginalPayload,FNode,FWalletKeys,Nil,LEPASA) then begin - Strings.Add('EPASA: '+LEPASA.ToString); - end else Strings.Add('No EPASA format'); - Strings.Add(Format('Payload type:%s length:%d',['0x'+IntToHex(OperationResume.OriginalPayload.payload_type,2), length(OperationResume.OriginalPayload.payload_raw)])); - if (Length(OperationResume.OriginalPayload.payload_raw)>0) then begin - If OperationResume.PrintablePayload<>'' then begin - Strings.Add(Format('Payload (human): %s',[OperationResume.PrintablePayload])); - end; - Strings.Add(Format('Payload (Hexadecimal): %s',[TCrypto.ToHexaString(OperationResume.OriginalPayload.payload_raw)])); - end; - If OperationResume.Balance>=0 then begin - Strings.Add(Format('Final balance: %s',[TAccountComp.FormatMoney(OperationResume.Balance)])); - end; - jsonObj := TPCJSONObject.Create; - Try - TPascalCoinJSONComp.FillOperationObject(OperationResume,FNode.Bank.BlocksCount, - FNode,FWalletKeys,Nil, - jsonObj); - Strings.Add('OPERATION JSON:'); - Strings.Add(jsonObj.ToJSON(False)); - Finally - jsonObj.Free; - end; -end; - Procedure TFRMWallet.InitMacOSMenu; {$IFDEF FPC} var @@ -1082,208 +419,6 @@ procedure TFRMWallet.FillOperationInformation(const Strings: TStrings; {$endif} end; - -procedure TFRMWallet.InitMenuForTesting; -var mi : TMenuItem; -begin -{$IFDEF TESTNET} - mi := TMenuItem.Create(MainMenu); - mi.Caption:='-'; - miAbout.Add(mi); - {$IFDEF TESTING_NO_POW_CHECK} - mi := TMenuItem.Create(MainMenu); - mi.Caption:='Create a block'; - mi.OnClick:=Test_CreateABlock; - {$IFnDEF FPC} - mi.ShortCut := TextToShortCut('CTRL+B'); - {$ENDIF} - miAbout.Add(mi); - {$ENDIF} - mi := TMenuItem.Create(MainMenu); - mi.Caption:='Connect/Disconnect'; - mi.OnClick:=Test_ConnectDisconnect; - {$IFnDEF FPC} - mi.ShortCut := TextToShortCut('CTRL+D'); - {$ENDIF} - miAbout.Add(mi); - - mi := TMenuItem.Create(MainMenu); - mi.Caption:='Create Random operations'; - mi.OnClick:=Test_RandomOperations; - miAbout.Add(mi); - mi := TMenuItem.Create(MainMenu); - mi.Caption:='Diagnostic Tool'; - mi.OnClick:=Test_ShowDiagnosticTool; - miAbout.Add(mi); - mi := TMenuItem.Create(MainMenu); - mi.Caption:='Show public keys state'; - mi.OnClick:=Test_ShowPublicKeys; - miAbout.Add(mi); - mi := TMenuItem.Create(MainMenu); - mi.Caption:='Show operations in memory'; - mi.OnClick:=Test_ShowOperationsInMemory; - miAbout.Add(mi); - mi := TMenuItem.Create(MainMenu); - mi.Caption:='Search accounts for private or swap to me'; - mi.OnClick:=Test_FindAccountsForPrivateBuyOrSwapToMe; - miAbout.Add(mi); -{$ELSE} -{$ENDIF} - mi := TMenuItem.Create(MainMenu); - mi.Caption:='-'; - MiOperations.Add(mi); - mi := TMenuItem.Create(MainMenu); - mi.Caption:='Ask for Free Account'; - mi.OnClick:=miAskForAccountClick; - MiOperations.Add(mi); -end; - -{$IFDEF TESTING_NO_POW_CHECK} -procedure TFRMWallet.Test_CreateABlock(Sender: TObject); -var ops, mempoolOps : TPCOperationsComp; - nba : TBlockAccount; - errors : String; - -begin - {$IFDEF TESTNET} - ops := TPCOperationsComp.Create(Nil); - Try - ops.bank := FNode.Bank; - mempoolOps := FNode.LockMempoolRead; - try - ops.CopyFrom(mempoolOps); - finally - FNode.UnlockMempoolRead; - end; - ops.BlockPayload.FromString(IntToStr(FNode.Bank.BlocksCount)); - ops.nonce := FNode.Bank.BlocksCount; - ops.UpdateTimestamp; - FNode.AddNewBlockChain(Nil,ops,errors); - finally - ops.Free; - end; - {$ELSE} - Raise Exception.Create('NOT ALLOWED!'); - {$ENDIF} -end; -{$ENDIF} - -{$IFDEF TESTNET} - -procedure TFRMWallet.Test_ConnectDisconnect(Sender: TObject); -begin - TNetData.NetData.NetConnectionsActive := Not TNetData.NetData.NetConnectionsActive; - Exit; - if FNode.NetServer.Active then begin - FNode.NetServer.Active := False; - end else begin - FNode.NetServer.Active := True; - end; -end; - -procedure TFRMWallet.Test_RandomOperations(Sender: TObject); -Var FRM : TFRMRandomOperations; -begin - FRM := TFRMRandomOperations.Create(Self); - Try - FRM.SourceNode := FNode; - FRM.SourceWalletKeys := FWalletKeys; - FRM.ShowModal; - finally - FRM.Free; - end; -end; - -{$ENDIF} - -procedure TFRMWallet.Test_ShowOperationsInMemory(Sender: TObject); -var LFRM : TFRMMemoText; - i, nOps : Integer; - Lslist : TStrings; -begin - Lslist := TStringList.Create; - try - TPCOperationsStorage.PCOperationsStorage.GetStats(Lslist); - nOps := TPCOperationsStorage.PCOperationsStorage.Count; - LFRM := TFRMMemoText.Create(Self); - try - LFRM.InitData('Operations in Memory '+IntToStr(nOps),Lslist.Text); - LFRM.ShowModal; - finally - LFRM.Free; - end; - finally - Lslist.Free; - end; -end; - -procedure TFRMWallet.Test_ShowPublicKeys(Sender: TObject); -var F : TFRMMemoText; - i : Integer; - sl : TStrings; - ak : TAccountKey; - nmin,nmax : Integer; - l : TList; - Pacsd : PAccountKeyStorageData; - acc : TAccount; -begin - sl := TStringList.Create; - try - for i:=0 to FNode.Bank.SafeBox.AccountsCount-1 do begin - acc := FNode.Bank.SafeBox.Account(i); - if acc.accountInfo.new_publicKey.EC_OpenSSL_NID<>0 then begin - sl.Add(Format('Account %d new public key %d %s',[acc.account, - acc.accountInfo.new_publicKey.EC_OpenSSL_NID, - TCrypto.ToHexaString(TAccountComp.AccountKey2RawString(acc.accountInfo.new_publicKey))])); - end; - end; - {$IFnDEF USE_ABSTRACTMEM} - l := TAccountKeyStorage.KS.LockList; - try - sl.Add(Format('%d public keys in TAccountKeyStorage data',[l.count])); - for i:=0 to l.count-1 do begin - Pacsd := l[i]; - if (Pacsd^.counter<=0) then begin - sl.Add(Format('%d/%d public keys counter %d',[i+1,l.count,Pacsd^.counter])); - end; - if FNode.Bank.SafeBox.OrderedAccountKeysList.IndexOfAccountKey(Pacsd^.ptrAccountKey^)<0 then begin - sl.Add(Format('%d/%d public keys counter %d Type %d NOT FOUND %s',[i+1,l.count,Pacsd^.counter, - Pacsd^.ptrAccountKey^.EC_OpenSSL_NID, - TCrypto.ToHexaString(TAccountComp.AccountKey2RawString(Pacsd^.ptrAccountKey^))])); - end; - end; - finally - TAccountKeyStorage.KS.UnlockList; - end; - sl.Add(Format('%d public keys in %d accounts',[FNode.Bank.SafeBox.OrderedAccountKeysList.Count,FNode.Bank.Safebox.AccountsCount])); - for i:=0 to FNode.Bank.SafeBox.OrderedAccountKeysList.Count-1 do begin - ak := FNode.Bank.SafeBox.OrderedAccountKeysList.AccountKey[i]; - if ( FNode.Bank.SafeBox.OrderedAccountKeysList.AccountKeyList[i].Count > 0) then begin - nmin := FNode.Bank.SafeBox.OrderedAccountKeysList.AccountKeyList[i].Get(0); - nmax := FNode.Bank.SafeBox.OrderedAccountKeysList.AccountKeyList[i].Get( FNode.Bank.SafeBox.OrderedAccountKeysList.AccountKeyList[i].Count-1 ); - end else begin - nmin := -1; nmax := -1; - end; - sl.Add(Format('%d/%d %d accounts (%d to %d) for key type %d %s',[ - i+1,FNode.Bank.SafeBox.OrderedAccountKeysList.Count, - FNode.Bank.SafeBox.OrderedAccountKeysList.AccountKeyList[i].Count, - nmin,nmax, - ak.EC_OpenSSL_NID, - TCrypto.ToHexaString(TAccountComp.AccountKey2RawString(ak)) ])); - end; - {$ENDIF} - F := TFRMMemoText.Create(Self); - try - F.InitData('Keys in safebox',sl.Text); - F.ShowModal; - finally - F.Free; - end; - finally - sl.Free; - end; -end; - function TFRMWallet.ForceMining: Boolean; begin Result := false; @@ -1307,25 +442,17 @@ procedure TFRMWallet.FormCreate(Sender: TObject); System.ReportMemoryLeaksOnShutdown := True; // Delphi memory leaks testing {$ENDIF} {$ENDIF} - FLastAccountsGridInvalidateTC := TPlatform.GetTickCount; + FLastNodesCacheUpdatedTS := Now; FBackgroundPanel := Nil; FBackgroundLabel := Nil; FThreadActivate := Nil; FMustProcessWalletChanged := false; - FMustProcessNetConnectionUpdated := false; FRPCServer := Nil; FNode := Nil; FPoolMiningServer := Nil; - FMinAccountBalance := 0; - FMaxAccountBalance := CT_MaxWalletAmount; - FMessagesUnreadCount := 0; - lblReceivedMessages.Visible := false; - memoNetConnections.Lines.Clear; - memoNetServers.Lines.Clear; - memoNetBlackLists.Lines.Clear; - memoMessages.Lines.Clear; - memoMessageToSend.Lines.Clear; + FrameInfo.lblReceivedMessages.Visible := false; + FUpdating := false; TimerUpdateStatus.Enabled := false; FIsActivated := false; @@ -1334,40 +461,45 @@ procedure TFRMWallet.FormCreate(Sender: TObject); StatusBar.Panels[i].Text := ''; end; FLog := TLog.Create(Self); - FLog.OnNewLog := OnNewLog; + FLog.OnNewLog := FrameLogs.OnNewLog; FLog.SaveTypes := []; If Not ForceDirectories(TNode.GetPascalCoinDataFolder) then raise Exception.Create('Cannot create dir: '+TNode.GetPascalCoinDataFolder); TSettings.Load; TSettings.OnChanged.Add(UpdateConfigChanged); FNodeNotifyEvents := TNodeNotifyEvents.Create(Self); FNodeNotifyEvents.OnBlocksChanged := OnNewAccount; - FNodeNotifyEvents.OnNodeMessageEvent := OnNodeMessageEvent; + FNodeNotifyEvents.OnNodeMessageEvent := FrameMessages.OnNodeMessageEvent; FNodeNotifyEvents.OnKeyActivity := OnNodeKeysActivity; + FAccountsGrid := TAccountsGrid.Create(Self); - FAccountsGrid.DrawGrid := dgAccounts; + FAccountsGrid.DrawGrid := FrameAccountExplorer.dgAccounts; FAccountsGrid.AllowMultiSelect := True; - FAccountsGrid.OnAccountsGridUpdatedData := OnAccountsGridUpdatedData; + FAccountsGrid.OnAccountsGridUpdatedData := FrameAccountExplorer.OnAccountsGridUpdatedData; FAccountsGrid.AccountsGridDatasource := acds_Node; + FrameAccountExplorer.AccountsGrid := FAccountsGrid; + FSelectedAccountsGrid := TAccountsGrid.Create(Self); FSelectedAccountsGrid.AccountsGridDatasource := acds_InternalList; - FSelectedAccountsGrid.DrawGrid := dgSelectedAccounts; - FSelectedAccountsGrid.OnUpdated := OnSelectedAccountsGridUpdated; + FSelectedAccountsGrid.DrawGrid := FrameAccountExplorer.dgSelectedAccounts; + FSelectedAccountsGrid.OnUpdated := FrameAccountExplorer.OnSelectedAccountsGridUpdated; + FrameAccountExplorer.SelectedAccountsGrid := FSelectedAccountsGrid; + FOperationsAccountGrid := TOperationsGrid.Create(Self); - FOperationsAccountGrid.DrawGrid := dgAccountOperations; + FOperationsAccountGrid.DrawGrid := FrameAccountExplorer.dgAccountOperations; FOperationsAccountGrid.MustShowAlwaysAnAccount := true; FOperationsAccountGrid.WalletKeys := FWalletKeys; FPendingOperationsGrid := TOperationsGrid.Create(Self); - FPendingOperationsGrid.DrawGrid := dgPendingOperations; + FPendingOperationsGrid.DrawGrid := FramePendingOperations.dgPendingOperations; FPendingOperationsGrid.AccountNumber := -1; // all FPendingOperationsGrid.PendingOperations := true; FPendingOperationsGrid.WalletKeys := FWalletKeys; FOperationsExplorerGrid := TOperationsGrid.Create(Self); - FOperationsExplorerGrid.DrawGrid := dgOperationsExplorer; + FOperationsExplorerGrid.DrawGrid := FrameOperationsExplorer.dgOperationsExplorer; FOperationsExplorerGrid.AccountNumber := -1; FOperationsExplorerGrid.PendingOperations := False; FOperationsExplorerGrid.WalletKeys := FWalletKeys; FBlockChainGrid := TBlockChainGrid.Create(Self); - FBlockChainGrid.DrawGrid := dgBlockChainExplorer; + FBlockChainGrid.DrawGrid := FrameBlockChainExplorer.dgBlockChainExplorer; FBlockChainGrid.ShowTimeAverageColumns:={$IFDEF SHOW_AVERAGE_TIME_STATS}True;{$ELSE}False;{$ENDIF} // FWalletKeys.OnChanged.Add( OnWalletChanged ); {$IFDEF USE_GNUGETTEXT} @@ -1377,20 +509,16 @@ procedure TFRMWallet.FormCreate(Sender: TObject); RetranslateComponent(self); {$ENDIF} // - UpdatePrivateKeys; - UpdateBlockChainState; + FrameAccountExplorer.UpdatePrivateKeys; + FrameInfo.UpdateBlockChainState; UpdateConnectionStatus; PageControl.ActivePage := tsOperations; - pcAccountsOptions.ActivePage := tsAccountOperations; - ebFilterOperationsStartBlock.Text := ''; - ebFilterOperationsEndBlock.Text := ''; - cbExploreMyAccounts.Checked:=True; // By default - cbExploreMyAccountsClick(nil); - - MinersBlocksFound := 0; - lblBuild.Caption := 'Build: '+CT_ClientAppVersion; + + FrameAccountExplorer.cbExploreMyAccountsClick(nil); + + FrameInfo.lblBuild.Caption := 'Build: '+CT_ClientAppVersion; {$IFDEF TESTNET} - lblBuild.Font.Color := clRed; + FrameInfo.lblBuild.Font.Color := clRed; {$ENDIF} PageControl.Enabled := False; PageControl.Visible := False; @@ -1406,16 +534,14 @@ procedure TFRMWallet.FormCreate(Sender: TObject); FBackgroundLabel.Font.Size := 18; FBackgroundLabel.Alignment := taCenter; FBackgroundLabel.WordWrap := True; - cbHashRateUnits.Items.Clear; - cbHashRateUnits.Items.Add('h/s'); - cbHashRateUnits.Items.Add('Kh/s'); - cbHashRateUnits.Items.Add('Mh/s'); - cbHashRateUnits.Items.Add('Gh/s'); - cbHashRateUnits.Items.Add('Th/s'); - cbHashRateUnits.Items.Add('Ph/s'); - cbHashRateUnits.Items.Add('Eh/s'); - // Things for testing purposes only - InitMenuForTesting; + + // set some frame properties + with FrameAccountExplorer do + begin + pcAccountsOptions.ActivePage := tsAccountOperations; + cbExploreMyAccounts.Checked:=True; // By default + end; + {$ifdef DARWIN} // this is macOS specific menu layout InitMacOSMenu; @@ -1423,47 +549,6 @@ procedure TFRMWallet.FormCreate(Sender: TObject); PageControl.ActivePageIndex := 0; end; -procedure TFRMWallet.ebHashRateBackBlocksKeyPress(Sender: TObject; var Key: char); -begin - if Key=#13 then ebHashRateBackBlocksExit(Nil); -end; - -procedure TFRMWallet.ebHashRateBackBlocksExit(Sender: TObject); -var i : Integer; -begin - If FUpdating then exit; - FUpdating := True; - Try - i := StrToIntDef(ebHashRateBackBlocks.Text,-1); - FBlockChainGrid.HashRateAverageBlocksCount:=i; - TSettings.HashRateAvgBlocksCount := FBlockChainGrid.HashRateAverageBlocksCount; - Finally - ebHashRateBackBlocks.Text := IntToStr(FBlockChainGrid.HashRateAverageBlocksCount); - FUpdating := false; - End; -end; - -procedure TFRMWallet.cbHashRateUnitsClick(Sender: TObject); -begin - If FUpdating then Exit; - FUpdating := True; - Try - case cbHashRateUnits.ItemIndex of - 0 : FBlockChainGrid.HashRateAs := hr_Unit; - 1 : FBlockChainGrid.HashRateAs := hr_Kilo; - 2 : FBlockChainGrid.HashRateAs := hr_Mega; - 3 : FBlockChainGrid.HashRateAs := hr_Giga; - 4 : FBlockChainGrid.HashRateAs := hr_Tera; - 5 : FBlockChainGrid.HashRateAs := hr_Peta; - 6 : FBlockChainGrid.HashRateAs := hr_Exa; - else FBlockChainGrid.HashRateAs := hr_Mega; - end; - TSettings.ShowHashRateAs := FBlockChainGrid.HashRateAs; - Finally - FUpdating := false; - End; -end; - procedure TFRMWallet.FormDestroy(Sender: TObject); Var i : Integer; step : String; @@ -1486,8 +571,8 @@ procedure TFRMWallet.FormDestroy(Sender: TObject); FOperationsAccountGrid.Node := Nil; FOperationsExplorerGrid.Node := Nil; FPendingOperationsGrid.Node := Nil; - FAccountsGrid.Node := Nil; - FSelectedAccountsGrid.Node := Nil; + FrameAccountExplorer.AccountsGrid.Node := Nil; + FrameAccountExplorer.SelectedAccountsGrid.Node := Nil; TNetData.NetData.OnReceivedHelloMessage := Nil; TNetData.NetData.OnStatisticsChanged := Nil; TNetData.NetData.OnNetConnectionsUpdated := Nil; @@ -1516,22 +601,105 @@ procedure TFRMWallet.FormDestroy(Sender: TObject); step := 'Processing messages 1'; Application.ProcessMessages; - step := 'Destroying Node'; - TNode.Node.Free; + step := 'Destroying Node'; + TNode.Node.Free; + + step := 'Destroying Wallet'; + FreeAndNil(FWalletKeys); + step := 'Processing messages 2'; + Application.ProcessMessages; + step := 'Destroying stringslist'; + Except + On E:Exception do begin + TLog.NewLog(lterror,Classname,'Error destroying Form step: '+step+' Errors ('+E.ClassName+'): ' +E.Message); + end; + End; + TLog.NewLog(ltinfo,Classname,'Destroying form - END'); + FreeAndNil(FLog); + Sleep(100); +end; + +procedure TFRMWallet.CheckIsReady; +Var isready : String; +begin + if Not Assigned(FNode) then Abort; + + if Not FNode.IsReady(isready) then begin + Raise Exception.Create('You cannot do this operation now:'+#10+#10+isready); + end; +end; + +procedure TFRMWallet.CM_WalletChanged(var Msg: TMessage); +begin + FrameAccountExplorer.UpdatePrivateKeys; + FMustProcessWalletChanged := false; +end; + +procedure TFRMWallet.DoUpdateAccounts; +begin + FrameAccountExplorer.UpdateAccounts(true); +end; + +procedure TFRMWallet.FinishedLoadingApp; +var LLockedMempool : TPCOperationsComp; + LFoundAccounts, i, LOnSafebox,LOnMempool : Integer; + Lpubkeys : TList; +begin + FNodeNotifyEvents.Node := FNode; + // Init + TNetData.NetData.OnReceivedHelloMessage := OnReceivedHelloMessage; + TNetData.NetData.OnStatisticsChanged := OnNetStatisticsChanged; + TNetData.NetData.OnNetConnectionsUpdated := FrameNodeStats.OnNetConnectionsUpdated; + TNetData.NetData.OnNodeServersUpdated := FrameNodeStats.OnNetNodeServersUpdated; + TNetData.NetData.OnBlackListUpdated := FrameNodeStats.OnNetBlackListUpdated; + + // + TimerUpdateStatus.Interval := 1000; + TimerUpdateStatus.Enabled := true; + // + FPoolMiningServer := TPoolMiningServer.Create; + FPoolMiningServer.Port := TSettings.JsonRpcMinerServerPort; + FPoolMiningServer.MinerAccountKey := GetAccountKeyForMiner; + FPoolMiningServer.MinerPayload := TEncoding.ANSI.GetBytes(TSettings.MinerName); + LLockedMempool := FNode.LockMempoolWrite; + try + LLockedMempool.AccountKey := GetAccountKeyForMiner; + finally + FNode.UnlockMempoolWrite; + end; + FPoolMiningServer.Active := TSettings.JsonRpcMinerServerActive; + FPoolMiningServer.OnMiningServerNewBlockFound := OnMiningServerNewBlockFound; + FreeAndNil(FBackgroundLabel); + FreeAndNil(FBackgroundPanel); + + PageControl.Visible:=True; + PageControl.Enabled:=True; - step := 'Destroying Wallet'; - FreeAndNil(FWalletKeys); - step := 'Processing messages 2'; - Application.ProcessMessages; - step := 'Destroying stringslist'; - Except - On E:Exception do begin - TLog.NewLog(lterror,Classname,'Error destroying Form step: '+step+' Errors ('+E.ClassName+'): ' +E.Message); - end; - End; - TLog.NewLog(ltinfo,Classname,'Destroying form - END'); - FreeAndNil(FLog); - Sleep(100); + FrameAccountExplorer.UpdatePrivateKeys; + // + LFoundAccounts := 0; + FNode.Bank.SafeBox.StartThreadSafe; + try + Lpubkeys := TList.Create; + Try + for i := 0 to FWalletKeys.Count-1 do begin + if (FWalletKeys.Key[i].HasPrivateKey) then begin + Lpubkeys.Add(FWalletKeys.Key[i].AccountKey); + end; + end; + if (Lpubkeys.Count>0) then begin + LFoundAccounts := FNode.GetAccountsAvailableByPublicKey(Lpubkeys,LOnSafebox,LOnMempool); + end else LFoundAccounts := 0; + Finally + Lpubkeys.Free; + End; + finally + FNode.Bank.SafeBox.EndThreadSave; + end; + if LFoundAccounts<1 then begin + // Will only ask if no accounts + TFRMAskForAccount.AskForAccount(Self,FNode,TNetData.NetData,FWalletKeys,GetAccountKeyForMiner); + end; end; procedure TFRMWallet.MiOperationsExplorerClick(Sender: TObject); @@ -1558,19 +726,6 @@ procedure TFRMWallet.MiRPCCallsClick(Sender: TObject); end; end; -procedure TFRMWallet.sbSearchAccountClick(Sender: TObject); -Var F : TFRMAccountSelect; -begin - F := TFRMAccountSelect.Create(Self); - try - F.Node := FNode; - F.WalletKeys := FWalletKeys; - F.ShowModal; - finally - F.Free; - end; -end; - function TFRMWallet.GetAccountKeyForMiner: TAccountKey; Var PK : TECPrivateKey; i : Integer; @@ -1631,11 +786,6 @@ procedure TFRMWallet.IPnodes1Click(Sender: TObject); End; end; -procedure TFRMWallet.lblReceivedMessagesClick(Sender: TObject); -begin - PageControl.ActivePage := tsMessages; -end; - procedure TFRMWallet.miAboutPascalCoinClick(Sender: TObject); begin With TFRMAbout.Create(Self) do @@ -1671,9 +821,9 @@ procedure TFRMWallet.MiAccountInformationClick(Sender: TObject); opr := FPendingOperationsGrid.OperationsResume.OperationResume[i-1]; end; end else if PageControl.ActivePage=tsMyAccounts then begin - accn := FAccountsGrid.AccountNumber(dgAccounts.Row); + accn := FrameAccountExplorer.AccountsGrid.AccountNumber(FrameAccountExplorer.dgAccounts.Row); if accn<0 then raise Exception.Create('Select an account'); - FillAccountInformation(strings,accn); + TFRMWalletInformation.FillAccountInformation(strings,accn); title := 'Account '+TAccountComp.AccountNumberToAccountTxtNumber(accn)+' info'; i := FOperationsAccountGrid.DrawGrid.Row; if (i>0) and (i<=FOperationsAccountGrid.OperationsResume.Count) then begin @@ -1684,7 +834,7 @@ procedure TFRMWallet.MiAccountInformationClick(Sender: TObject); if accn>=0 then strings.Add('') else title := 'Operation info'; strings.Add('Operation info:'); - FillOperationInformation(strings,opr); + TFRMWalletInformation.FillOperationInformation(strings,opr); end else if accn<0 then Raise Exception.Create('No info available'); F := TFRMMemoText.Create(Self); Try @@ -1705,8 +855,8 @@ procedure TFRMWallet.MiAddaccounttoSelectedClick(Sender: TObject); begin PageControl.ActivePage := tsMyAccounts; PageControlChange(Nil); - pcAccountsOptions.ActivePage := tsMultiSelectAccounts; - sbSelectedAccountsAddClick(Sender); + FrameAccountExplorer.pcAccountsOptions.ActivePage := FrameAccountExplorer.tsMultiSelectAccounts; + FrameAccountExplorer.sbSelectedAccountsAddClick(Sender); end; procedure TFRMWallet.miAskForAccountClick(Sender: TObject); @@ -1730,216 +880,11 @@ procedure TFRMWallet.MiDecodePayloadClick(Sender: TObject); end; end; -procedure TFRMWallet.Test_FindAccountsForPrivateBuyOrSwapToMe(Sender: TObject); -{ This procedure will search in Safebox all accounts in "for_private_sale" state - or in "for_account_swap" that can be self-signed using one of my private keys - } - - function CaptureSender0Coins(var AAccountSender0Coins : TAccount; var ANeededWalletKey : TWalletKey) : Boolean; - var ii : Integer; - begin - // - Result := False; - for ii := 0 to WalletKeys.AccountsKeyList.Count-1 do begin - if WalletKeys.AccountsKeyList.AccountKeyList[ii].Count>0 then begin - if WalletKeys.TryGetKey(WalletKeys.AccountsKeyList.AccountKey[ii],ANeededWalletKey) then begin - AAccountSender0Coins := FNode.Bank.SafeBox.Account( WalletKeys.AccountsKeyList.AccountKeyList[ii].Get(0) ); - Result := True; - end; - end; - end; - - end; - - -var i : Integer; - LLines : TStrings; - LAccount, LAccountSender0Coins : TAccount; - LAccountOpDesc : String; - LCountAccountsFound_total, LCountAccountsFound_Operation : Integer; - LNeededWalletKey : TWalletKey; - s : String; - LOpTransaction : TOpTransaction; - LOperationsHashTree, LGlobalOperationsHashTree : TOperationsHashTree; - LStream : TStream; - LRaw : TRawBytes; - LFRM : TFRMMemoText; - LOpPayload : TOperationPayload; -begin - if Not WalletKeys.IsValidPassword then raise Exception.Create('Your wallet keys are locked'); - LOpPayload := CT_TOperationPayload_NUL; - if InputQuery('Search ATOMIC SWAP by SECRET','Insert SECRET value (use 0x... for Hexadecimal, otherwise will be a String)',s) then begin - if s.StartsWith('0x') then begin - if not UCommon.TryHex2Bytes(s,LOpPayload.payload_raw) then raise Exception.Create('SECRET value is not an Hexadecimal'+#10+s); - end else begin - LOpPayload.payload_raw.FromString(s); - end; - end; - LCountAccountsFound_total := 0; - LCountAccountsFound_Operation := 0; - LLines := TStringList.Create; - LGlobalOperationsHashTree := TOperationsHashTree.Create; - try - for i:=0 to FNode.Bank.SafeBox.AccountsCount-1 do begin - LAccountOpDesc := ''; - LAccount := FNode.Bank.SafeBox.Account(i); - - LOpTransaction := Nil; - Try - Case LAccount.accountInfo.state of - as_ForSale : begin - if Not TAccountComp.IsNullAccountKey( LAccount.accountInfo.new_publicKey ) then begin - if Not WalletKeys.TryGetKey(LAccount.accountInfo.new_publicKey,LNeededWalletKey) then Continue; - if Not Assigned(LNeededWalletKey.PrivateKey) then Continue; // Key not available! - end else Continue; - // Private sale to me - // Is in time? - if TAccountComp.IsAccountLocked(LAccount.accountInfo,FNode.Bank.BlocksCount) then begin - // - if LAccount.balance>=LAccount.accountInfo.price then begin - LAccountOpDesc := Format('Account %s is for private sale to me and with enough balance to pay %s (balance %s)',[ - TAccountComp.AccountNumberToAccountTxtNumber(LAccount.account), - TAccountComp.FormatMoney(LAccount.accountInfo.price), - TAccountComp.FormatMoney(LAccount.balance)]); - // No key needed... just a transaction SELF SIGNED - LOpTransaction := TOpBuyAccount.CreateBuy(FNode.Bank.SafeBox.CurrentProtocol, - LAccount.account, LAccount.n_operation+1, - LAccount.account, LAccount.accountInfo.account_to_pay, LAccount.accountInfo.price, - 0,0, - LAccount.accountInfo.new_publicKey, - LNeededWalletKey.PrivateKey, - LOpPayload); - end else begin - LAccountOpDesc := Format('Account %s is for private sale to me but needs a Buy operation paying %s PASC (%s pending)',[ - TAccountComp.AccountNumberToAccountTxtNumber(LAccount.account), - TAccountComp.FormatMoney(LAccount.accountInfo.price), - TAccountComp.FormatMoney(LAccount.accountInfo.price - LAccount.balance)]); - end; - end else begin - LAccountOpDesc := Format('Account %s is for private sale to me but is out-of-lock period',[TAccountComp.AccountNumberToAccountTxtNumber(LAccount.account)]); - end; - end; - as_ForAtomicAccountSwap : begin - if Not WalletKeys.TryGetKey(LAccount.accountInfo.new_publicKey,LNeededWalletKey) then Continue; - if TAccountComp.IsAccountLocked(LAccount.accountInfo,FNode.Bank.BlocksCount) then begin - if TAccountComp.IsValidAccountInfoHashLockKey(LAccount.accountInfo,LOpPayload.payload_raw) then begin - // Atomic Account swap using provided SECRET - LAccountOpDesc := Format('Account %s is for Atomic Account Swap to me using SECRET %s',[TAccountComp.AccountNumberToAccountTxtNumber(LAccount.account),UCommon.Bytes2Hex(LOpPayload.payload_raw,True)]); - // - // No key needed... just a Buy Operation SELF SIGNED - LOpTransaction := TOpBuyAccount.CreateBuy(FNode.Bank.SafeBox.CurrentProtocol, - LAccount.account, LAccount.n_operation+1, - LAccount.account, LAccount.accountInfo.account_to_pay, LAccount.accountInfo.price, - 0,0, - LAccount.accountInfo.new_publicKey, - LNeededWalletKey.PrivateKey, - LOpPayload); - end else begin - LAccountOpDesc := Format('Account %s is for Atomic Account Swap to me but SECRET %s is not valid',[TAccountComp.AccountNumberToAccountTxtNumber(LAccount.account),UCommon.Bytes2Hex(LOpPayload.payload_raw,True)]); - end; - end else begin - LAccountOpDesc := Format('Account %s is for Atomic Account Swap to me but is out-of-lock period',[TAccountComp.AccountNumberToAccountTxtNumber(LAccount.account)]); - end; - - end; - as_ForAtomicCoinSwap : begin - if Not TAccountComp.IsValidAccountInfoHashLockKey(LAccount.accountInfo,LOpPayload.payload_raw) then Continue; - // Atomic Coin swap using provided SECRET - if TAccountComp.IsAccountLocked(LAccount.accountInfo,FNode.Bank.BlocksCount) then begin - // Single transaction using amount 0 from ANY sender - if CaptureSender0Coins(LAccountSender0Coins,LNeededWalletKey) then begin - // Atomic Account swap using provided SECRET - LAccountOpDesc := Format('Account %s is for Atomic Coin Swap to me using SECRET %s',[TAccountComp.AccountNumberToAccountTxtNumber(LAccount.account),UCommon.Bytes2Hex(LOpPayload.payload_raw,True)]); - // - // No key needed... just a transaction SELF SIGNED - LOpTransaction := TOpTransaction.CreateTransaction(FNode.Bank.SafeBox.CurrentProtocol, - LAccountSender0Coins.account, LAccountSender0Coins.n_operation+1, - LAccount.account, - LNeededWalletKey.PrivateKey, - 0,0, // No Amount no Fee - LOpPayload); - end else begin - LAccountOpDesc := Format('Account %s is for Atomic Coin Swap using SECRET %s but I have no key to sign',[TAccountComp.AccountNumberToAccountTxtNumber(LAccount.account),UCommon.Bytes2Hex(LOpPayload.payload_raw,True)]); - end; - end else begin - LAccountOpDesc := Format('Account %s is for Atomic Coin Swap using SECRET %s but is out-of-lock period',[TAccountComp.AccountNumberToAccountTxtNumber(LAccount.account),UCommon.Bytes2Hex(LOpPayload.payload_raw,True)]); - end; - end; - else Continue; - End; - - // Do - Inc(LCountAccountsFound_total); - LLines.Add(Format('%s',[LAccountOpDesc])); - if Assigned(LOpTransaction) then begin - Inc(LCountAccountsFound_Operation); - LOperationsHashTree := TOperationsHashTree.Create; - LStream := TMemoryStream.Create; - try - LOperationsHashTree.AddOperationToHashTree(LOpTransaction); - LGlobalOperationsHashTree.AddOperationToHashTree(LOpTransaction); - LLines.Add(Format('Operation: %s',[LOpTransaction.ToString])); - LOperationsHashTree.SaveOperationsHashTreeToStream(LStream,False); - LRaw.FromStream(LStream); - LLines.Add(Format('rawoperations (for JSON-RPC call): %s',[LRaw.ToHexaString])); - finally - LOperationsHashTree.Free; - LStream.Free; - end; - end; - - Finally - FreeAndNil(LOpTransaction); - End; - end; // For - LLines.Add(''); - LLines.Add(Format('Found %d of %d available account from a Safebox with %d accounts',[ - LCountAccountsFound_Operation, - LCountAccountsFound_total, - FNode.Bank.SafeBox.AccountsCount])); - LStream := TMemoryStream.Create; - try - LGlobalOperationsHashTree.SaveOperationsHashTreeToStream(LStream,False); - LRaw.FromStream(LStream); - LLines.Add(Format('rawoperations (for JSON-RPC call) of %d operations: %s',[LGlobalOperationsHashTree.OperationsCount, LRaw.ToHexaString])); - finally - LStream.Free; - end; - // - LFRM := TFRMMemoText.Create(Self); - try - LFRM.InitData('',LLines.Text); - LFRM.ShowModal; - finally - LFRM.Free; - end; - finally - LLines.Free; - LGlobalOperationsHashTree.Free; - end; -end; - -procedure TFRMWallet.Test_ShowDiagnosticTool(Sender: TObject); -{$IFDEF TESTNET} -var - LDialog : TFRMDiagnosticTool; -{$ENDIF} -begin -{$IFDEF TESTNET} - LDialog := TFRMDiagnosticTool.Create(Nil); - try - LDialog.ShowModal; - finally - LDialog.Free; - end; -{$ENDIF} -end; - procedure TFRMWallet.MiFindaccountClick(Sender: TObject); begin PageControl.ActivePage := tsMyAccounts; PageControlChange(Nil); - ebFindAccountNumber.SetFocus; + FrameAccountExplorer.ebFindAccountNumber.SetFocus; end; procedure TFRMWallet.MiFindnextaccountwithhighbalanceClick(Sender: TObject); @@ -1949,7 +894,7 @@ procedure TFRMWallet.MiFindnextaccountwithhighbalanceClick(Sender: TObject); begin PageControl.ActivePage := tsMyAccounts; PageControlChange(Nil); - an64 := FAccountsGrid.AccountNumber(dgAccounts.Row); + an64 := FrameAccountExplorer.AccountsGrid.AccountNumber(FrameAccountExplorer.dgAccounts.Row); if an64<0 then an := 0 else an := an64; If an>=FNode.Bank.SafeBox.AccountsCount then exit; @@ -1958,7 +903,7 @@ procedure TFRMWallet.MiFindnextaccountwithhighbalanceClick(Sender: TObject); if FNode.Bank.SafeBox.Account(an).balance>start.balance then break else inc(an); end; - if (an=FNode.Bank.SafeBox.AccountsCount then exit; @@ -1996,7 +941,7 @@ procedure TFRMWallet.MiFindpreviousaccountwithhighbalanceClick(Sender: TObject); if FNode.Bank.SafeBox.Account(an).balance>start.balance then break else dec(an); end; - if (FNode.Bank.SafeBox.Account(an).balance>start.balance) then FAccountsGrid.MoveRowToAccount(an) + if (FNode.Bank.SafeBox.Account(an).balance>start.balance) then FrameAccountExplorer.AccountsGrid.MoveRowToAccount(an) else raise Exception.Create('Not found any account lower than '+TAccountComp.AccountNumberToAccountTxtNumber(start.account)+' with balance higher than '+ TAccountComp.FormatMoney(start.balance)); end; @@ -2004,8 +949,8 @@ procedure TFRMWallet.MiFindpreviousaccountwithhighbalanceClick(Sender: TObject); procedure TFRMWallet.MiMultiaccountoperationClick(Sender: TObject); begin PageControl.ActivePage := tsMyAccounts; - pcAccountsOptions.ActivePage := tsMultiSelectAccounts; - bbSelectedAccountsOperationClick(Sender); + FrameAccountExplorer.pcAccountsOptions.ActivePage := FrameAccountExplorer.tsMultiSelectAccounts; + FrameAccountExplorer.bbSelectedAccountsOperationClick(Sender); end; procedure TFRMWallet.miNewOperationClick(Sender: TObject); @@ -2016,7 +961,7 @@ procedure TFRMWallet.miNewOperationClick(Sender: TObject); Try l := TOrderedCardinalList.Create; try - If FAccountsGrid.SelectedAccounts(l)<1 then raise Exception.Create('No row selected'); + If FrameAccountExplorer.AccountsGrid.SelectedAccounts(l)<1 then raise Exception.Create('No row selected'); SenderAccounts.CopyFrom(l); finally l.Free; @@ -2052,7 +997,7 @@ procedure TFRMWallet.miPrivatekeysClick(Sender: TObject); Try FRM.WalletKeys := FWalletKeys; FRM.ShowModal; - UpdatePrivateKeys; + FrameAccountExplorer.UpdatePrivateKeys; Finally FRM.Free; End; @@ -2062,19 +1007,8 @@ procedure TFRMWallet.MiRemoveaccountfromselectedClick(Sender: TObject); begin PageControl.ActivePage := tsMyAccounts; PageControlChange(Nil); - pcAccountsOptions.ActivePage := tsMultiSelectAccounts; - sbSelectedAccountsDelClick(Sender); -end; - -procedure TFRMWallet.OnAccountsGridUpdatedData(Sender: TObject); -begin - if FAccountsGrid.IsUpdatingData then begin - lblAccountsCount.Caption := '(Calculating)'; - lblAccountsBalance.Caption := '(Calculating)'; - end else begin - lblAccountsCount.Caption := IntToStr(FAccountsGrid.AccountsCount); - lblAccountsBalance.Caption := TAccountComp.FormatMoney(FAccountsGrid.AccountsBalance); - end; + FrameAccountExplorer.pcAccountsOptions.ActivePage := FrameAccountExplorer.tsMultiSelectAccounts; + FrameAccountExplorer.sbSelectedAccountsDelClick(Sender); end; procedure TFRMWallet.OnMiningServerNewBlockFound(Sender: TObject); @@ -2082,103 +1016,6 @@ procedure TFRMWallet.OnMiningServerNewBlockFound(Sender: TObject); FPoolMiningServer.MinerAccountKey := GetAccountKeyForMiner; end; -procedure TFRMWallet.OnNetBlackListUpdated(Sender: TObject); -Const CT_TRUE_FALSE : Array[Boolean] Of AnsiString = ('FALSE','TRUE'); -Var i,j,n : integer; - P : PNodeServerAddress; - l : TList; - strings : TStrings; -begin - l := TNetData.NetData.NodeServersAddresses.LockList; - try - strings := memoNetBlackLists.Lines; - strings.BeginUpdate; - Try - strings.Clear; - strings.Add('BlackList Updated: '+DateTimeToStr(now)+' by TID:'+IntToHex(PtrInt(TThread.CurrentThread.ThreadID),8)); - j := 0; n:=0; - for i := 0 to l.Count - 1 do begin - P := l[i]; - if (P^.is_blacklisted) then begin - inc(n); - if Not P^.its_myself then begin - inc(j); - strings.Add(Format('Blacklist IP:%s:%d LastConnection:%s Reason: %s', - [ - P^.ip,P^.port, - DateTimeToStr(UnivDateTime2LocalDateTime( UnixToUnivDateTime(P^.last_connection))),P^.BlackListText])); - end; - end; - end; - Strings.Add(Format('Total Blacklisted IPs: %d (Total %d)',[j,n])); - Finally - strings.EndUpdate; - End; - finally - TNetData.NetData.NodeServersAddresses.UnlockList; - end; -end; - -procedure TFRMWallet.OnNetConnectionsUpdated(Sender: TObject); -begin - if FMustProcessNetConnectionUpdated then exit; - FMustProcessNetConnectionUpdated := true; - PostMessage(Self.Handle,CM_PC_NetConnectionUpdated,0,0); -end; - -procedure TFRMWallet.OnNetNodeServersUpdated(Sender: TObject); -Var i : integer; - P : PNodeServerAddress; - l : TList; - strings : TStrings; - s : String; -begin - l := TNetData.NetData.NodeServersAddresses.LockList; - try - strings := memoNetServers.Lines; - strings.BeginUpdate; - Try - strings.Clear; - strings.Add('NodeServers Updated: '+DateTimeToStr(now) +' Count: '+inttostr(l.Count)); - for i := 0 to l.Count - 1 do begin - P := l[i]; - if Not (P^.is_blacklisted) then begin - s := Format('Server IP:%s:%d',[P^.ip,P^.port]); - if (P^.last_connection_by_me>0) then begin - s := s + ' [Server] '; - end; - - if Assigned(P.netConnection) then begin - If P.last_connection>0 then s := s+ ' ** ACTIVE **' - else s := s+' ** TRYING TO CONNECT **'; - end; - if P.its_myself then begin - s := s+' ** NOT VALID ** '+P.BlackListText; - end; - if P.last_connection>0 then begin - s := s + ' Last connection: '+DateTimeToStr(UnivDateTime2LocalDateTime( UnixToUnivDateTime(P^.last_connection))); - end; - if P.last_connection_by_server>0 then begin - s := s + ' Last server connection: '+DateTimeToStr(UnivDateTime2LocalDateTime( UnixToUnivDateTime(P^.last_connection_by_server))); - end; - if (P.last_attempt_to_connect>0) then begin - s := s + ' Last attempt to connect: '+DateTimeToStr(P^.last_attempt_to_connect); - end; - if (P.total_failed_attemps_to_connect>0) then begin - s := s + ' (Attempts: '+inttostr(P^.total_failed_attemps_to_connect)+')'; - end; - - strings.Add(s); - end; - end; - Finally - strings.EndUpdate; - End; - finally - TNetData.NetData.NodeServersAddresses.UnlockList; - end; -end; - procedure TFRMWallet.OnNetStatisticsChanged(Sender: TObject); Var NS : TNetStatistics; begin @@ -2199,8 +1036,8 @@ procedure TFRMWallet.OnNetStatisticsChanged(Sender: TObject); procedure TFRMWallet.OnNewAccount(Sender: TObject); begin Try - UpdateAccounts(false); - UpdateBlockChainState; + FrameAccountExplorer.UpdateAccounts(false); + FrameInfo.UpdateBlockChainState; Except On E:Exception do begin E.Message := 'Exception at OnNewAccount '+E.ClassName+': '+E.Message; @@ -2210,51 +1047,6 @@ procedure TFRMWallet.OnNewAccount(Sender: TObject); end; end; -procedure TFRMWallet.OnNewLog(logtype: TLogType; Time : TDateTime; ThreadID : TThreadID; const sender,logtext: String); -Var s : AnsiString; -begin - if (logtype=ltdebug) And (Not cbShowDebugLogs.Checked) then exit; - if ThreadID=MainThreadID then s := ' MAIN:' else s:=' TID:'; - if MemoLogs.Lines.Count>300 then begin - // Limit max lines in logs... - memoLogs.Lines.BeginUpdate; - try - while memoLogs.Lines.Count>250 do memoLogs.Lines.Delete(0); - finally - memoLogs.Lines.EndUpdate; - end; - end; - memoLogs.Lines.Add(formatDateTime('dd/mm/yyyy hh:nn:ss.zzz',Time)+s+IntToHex(PtrInt(ThreadID),8)+' ['+CT_LogType[Logtype]+'] <'+sender+'> '+logtext); - // -end; - -procedure TFRMWallet.OnNodeMessageEvent(NetConnection: TNetConnection; MessageData: String); -Var s : String; -begin - inc(FMessagesUnreadCount); - if Assigned(NetConnection) then begin - s := DateTimeToStr(now)+' Message received from '+NetConnection.ClientRemoteAddr; - memoMessages.Lines.Add(DateTimeToStr(now)+' Message received from '+NetConnection.ClientRemoteAddr+' Length '+inttostr(Length(MessageData))+' bytes'); - memoMessages.Lines.Add('RECEIVED> '+MessageData); - if TSettings.ShowModalMessages then begin - s := DateTimeToStr(now)+' Message from '+NetConnection.ClientRemoteAddr+#10+ - 'Length '+inttostr(length(MessageData))+' bytes'+#10+#10; - if TCrypto.IsHumanReadable(TEncoding.ANSI.GetBytes(MessageData)) then begin - s := s + MessageData; - end else begin - s := s +'Value in hexadecimal:'+#10+ - TCrypto.ToHexaString(TEncoding.ANSI.GetBytes(MessageData)); - end; - Application.MessageBox(PChar(s),PChar(Application.Title),MB_ICONINFORMATION+MB_OK); - end; - end else begin - memoMessages.Lines.Add(DateTimeToStr(now)+' Internal message: '+MessageData); - end; - if FMessagesUnreadCount>1 then lblReceivedMessages.Caption := Format('You have received %d messages',[FMessagesUnreadCount]) - else lblReceivedMessages.Caption := 'You have received 1 message'; - lblReceivedMessages.Visible := true; -end; - procedure TFRMWallet.OnNodeKeysActivity(Sender: TObject); begin DoUpdateAccounts; @@ -2278,12 +1070,6 @@ procedure TFRMWallet.OnReceivedHelloMessage(Sender: TObject); TNode.Node.PeerCache := s; end; -procedure TFRMWallet.OnSelectedAccountsGridUpdated(Sender: TObject); -begin - lblSelectedAccountsCount.Caption := Inttostr(FSelectedAccountsGrid.AccountsCount); - lblSelectedAccountsBalance.Caption := TAccountComp.FormatMoney( FSelectedAccountsGrid.AccountsBalance ); -end; - procedure TFRMWallet.OnWalletChanged(Sender: TObject); begin if FMustProcessWalletChanged then exit; @@ -2294,113 +1080,50 @@ procedure TFRMWallet.OnWalletChanged(Sender: TObject); procedure TFRMWallet.PageControlChange(Sender: TObject); begin MiDecodePayload.Enabled := false; + if PageControl.ActivePage=tsMyAccounts then begin - FAccountsGrid.Node := FNode; + FrameAccountExplorer.AccountsGrid.Node := FNode; MiDecodePayload.Enabled := true; - FSelectedAccountsGrid.Node := FNode; + FrameAccountExplorer.SelectedAccountsGrid.Node := FNode; end else begin - FAccountsGrid.Node := Nil; - FSelectedAccountsGrid.Node := Nil; + FrameAccountExplorer.AccountsGrid.Node := Nil; + FrameAccountExplorer.SelectedAccountsGrid.Node := Nil; end; + if PageControl.ActivePage=tsPendingOperations then begin FPendingOperationsGrid.Node := FNode; MiDecodePayload.Enabled := true; - end else FPendingOperationsGrid.Node := Nil; - if PageControl.ActivePage=tsBlockChain then FBlockChainGrid.Node := FNode - else FBlockChainGrid.Node := Nil; - if PageControl.ActivePage=tsOperations then begin - FOperationsExplorerGrid.Node := FNode; - MiDecodePayload.Enabled := true; - end else FOperationsExplorerGrid.Node := Nil; - if PageControl.ActivePage=tsMessages then begin - UpdateAvailableConnections; - FMessagesUnreadCount := 0; - lblReceivedMessages.Visible := false; + end else begin + FPendingOperationsGrid.Node := Nil; end; -end; - -procedure TFRMWallet.sbSelectedAccountsAddAllClick(Sender: TObject); -Var lsource,ltarget : TOrderedCardinalList; - i : Integer; -begin - lsource := FAccountsGrid.LockAccountsList; - Try - ltarget := FSelectedAccountsGrid.LockAccountsList; - Try - for i := 0 to lsource.Count-1 do begin - if FWalletKeys.IndexOfAccountKey(FNode.Bank.SafeBox.Account(lsource.Get(i)).accountInfo.accountKey)<0 then raise Exception.Create(Format('You cannot operate with account %d because private key not found in your wallet',[lsource.Get(i)])); - ltarget.Add(lsource.Get(i)); - end; - Finally - FSelectedAccountsGrid.UnlockAccountsList; - End; - Finally - FAccountsGrid.UnlockAccountsList; - End; -end; - -procedure TFRMWallet.sbSelectedAccountsAddClick(Sender: TObject); -Var l, selected : TOrderedCardinalList; - an : Int64; - i : Integer; -begin - an := FAccountsGrid.AccountNumber(dgAccounts.Row); - if (an<0) then raise Exception.Create('No account selected'); - if FWalletKeys.IndexOfAccountKey(FNode.Bank.SafeBox.Account(an).accountInfo.accountkey)<0 then - raise Exception.Create(Format('You cannot add %s account because private key not found in your wallet.'#10+#10+'You''re not the owner!', - [TAccountComp.AccountNumberToAccountTxtNumber(an)])); - // Add - l := FSelectedAccountsGrid.LockAccountsList; - selected := TOrderedCardinalList.Create; - Try - FAccountsGrid.SelectedAccounts(selected); - for i := 0 to selected.Count-1 do begin - l.Add(selected.Get(i)); - end; - Finally - selected.Free; - FSelectedAccountsGrid.UnlockAccountsList; - End; -end; -procedure TFRMWallet.sbSelectedAccountsDelAllClick(Sender: TObject); -Var l : TOrderedCardinalList; -begin - l := FSelectedAccountsGrid.LockAccountsList; - try - l.Clear; - finally - FSelectedAccountsGrid.UnlockAccountsList; + if PageControl.ActivePage=tsBlockChain then + begin + FBlockChainGrid.Node := FNode; + end else begin + FBlockChainGrid.Node := Nil; end; -end; -procedure TFRMWallet.sbSelectedAccountsDelClick(Sender: TObject); -Var an : Int64; - l : TOrderedCardinalList; -begin - l := FSelectedAccountsGrid.LockAccountsList; - try - an := FSelectedAccountsGrid.AccountNumber(dgSelectedAccounts.Row); - if an>=0 then l.Remove(an); - finally - FSelectedAccountsGrid.UnlockAccountsList; + if PageControl.ActivePage=tsOperations then begin + FOperationsExplorerGrid.Node := FNode; + MiDecodePayload.Enabled := true; + end else begin + FOperationsExplorerGrid.Node := Nil; end; -end; -procedure TFRMWallet.SetMinersBlocksFound(const Value: Integer); -begin - FMinersBlocksFound := Value; - lblBlocksFound.Caption := Inttostr(Value); - if Value>0 then lblBlocksFound.Font.Color := clGreen - else lblBlocksFound.Font.Color := clDkGray; + if PageControl.ActivePage=tsMessages then begin + FrameMessages.UpdateAvailableConnections; + FrameMessages.MessagesUnreadCount := 0; + FrameInfo.lblReceivedMessages.Visible := false; + end; end; procedure TFRMWallet.TimerUpdateStatusTimer(Sender: TObject); begin Try UpdateConnectionStatus; - UpdateBlockChainState; - UpdateNodeStatus; + FrameInfo.UpdateBlockChainState; + FrameInfo.UpdateNodeStatus; Except On E:Exception do begin E.Message := 'Exception at TimerUpdate '+E.ClassName+': '+E.Message; @@ -2409,153 +1132,6 @@ procedure TFRMWallet.TimerUpdateStatusTimer(Sender: TObject); End; end; -procedure TFRMWallet.UpdateAccounts(RefreshData : Boolean); -Var accl : TOrderedCardinalList; - l : TOrderedCardinalList; - i,j,k : Integer; - c : Cardinal; - LApplyfilter : Boolean; - acc : TAccount; - LFilters : TAccountsGridFilter; -begin - If Not Assigned(FWalletKeys) Then exit; - if Not Assigned(FNode) then Exit; - - if Not RefreshData then begin - if TPlatform.GetElapsedMilliseconds(FLastAccountsGridInvalidateTC)>1000 then begin - FLastAccountsGridInvalidateTC := TPlatform.GetTickCount; - dgAccounts.Invalidate; - end; - exit; - end; - LApplyfilter := (cbFilterAccounts.Checked) and ((FMinAccountBalance>0) Or ((FMaxAccountBalance=0))); - if (Not cbExploreMyAccounts.Checked) And (not LApplyfilter) then begin - FAccountsGrid.AccountsGridDatasource := acds_Node; - FAccountsGrid.UpdateData; - end else begin - LFilters := FAccountsGrid.AccountsGridFilter; - LFilters.MinBalance := FMinAccountBalance; - LFilters.MaxBalance := FMaxAccountBalance; - if cbExploreMyAccounts.Checked then begin - //FNode.Bank.SafeBox.StartThreadSafe; - try - LFilters.OrderedAccountsKeyList := FWalletKeys.AccountsKeyList; - if cbMyPrivateKeys.ItemIndex>0 then begin - i := PtrInt(cbMyPrivateKeys.Items.Objects[cbMyPrivateKeys.ItemIndex]); - if (i>=0) And (i; -begin - if Not TNetData.NetData.NetConnections.TryLockList(100,l) then exit; - try - lbNetConnections.Items.BeginUpdate; - Try - lbNetConnections.Items.Clear; - for i := 0 to l.Count - 1 do begin - NC := l[i]; - if NC.Connected then begin - if NC is TNetServerClient then begin - if Not NC.IsMyselfServer then begin - lbNetConnections.Items.AddObject(Format('Client: IP:%s',[NC.ClientRemoteAddr]),NC); - end; - end else begin - if Not NC.IsMyselfServer then begin - lbNetConnections.Items.AddObject(Format('Server: IP:%s',[NC.ClientRemoteAddr]),NC); - end; - end; - end; - end; - Finally - lbNetConnections.Items.EndUpdate; - End; - finally - TNetData.NetData.NetConnections.UnlockList; - end; -end; - -procedure TFRMWallet.UpdateBlockChainState; -Var isMining : boolean; - i,mc : Integer; - s : String; - f, favg : real; - LLockedMempool : TPCOperationsComp; -begin - UpdateNodeStatus; - mc := 0; - if Assigned(FNode) then begin - if FNode.Bank.BlocksCount>0 then begin - lblCurrentBlock.Caption := Inttostr(FNode.Bank.BlocksCount)+' (0..'+Inttostr(FNode.Bank.BlocksCount-1)+')'; ; - end else lblCurrentBlock.Caption := '(none)'; - lblCurrentAccounts.Caption := Inttostr(FNode.Bank.AccountsCount); - lblCurrentBlockTime.Caption := UnixTimeToLocalElapsedTime(FNode.Bank.LastOperationBlock.timestamp); - LLockedMempool := FNode.LockMempoolRead; - try - lblOperationsPending.Caption := Inttostr(LLockedMempool.Count); - lblCurrentDifficulty.Caption := InttoHex(LLockedMempool.OperationBlock.compact_target,8); - finally - FNode.UnlockMempoolRead; - end; - favg := FNode.Bank.GetActualTargetSecondsAverage(CT_CalcNewTargetBlocksAverage); - f := (CT_NewLineSecondsAvg - favg) / CT_NewLineSecondsAvg; - lblTimeAverage.Caption := 'Last '+Inttostr(CT_CalcNewTargetBlocksAverage)+': '+FormatFloat('0.0',favg)+' sec. (Optimal '+Inttostr(CT_NewLineSecondsAvg)+'s) Deviation '+FormatFloat('0.00%',f*100); - if favg>=CT_NewLineSecondsAvg then begin - lblTimeAverage.Font.Color := clNavy; - end else begin - lblTimeAverage.Font.Color := clOlive; - end; - lblTimeAverageAux.Caption := Format('Last %d: %s sec. - %d: %s sec. - %d: %s sec. - %d: %s sec. - %d: %s sec.',[ - CT_CalcNewTargetBlocksAverage * 2 ,FormatFloat('0.0',FNode.Bank.GetActualTargetSecondsAverage(CT_CalcNewTargetBlocksAverage * 2)), - ((CT_CalcNewTargetBlocksAverage * 3) DIV 2) ,FormatFloat('0.0',FNode.Bank.GetActualTargetSecondsAverage((CT_CalcNewTargetBlocksAverage * 3) DIV 2)), - ((CT_CalcNewTargetBlocksAverage DIV 4)*3),FormatFloat('0.0',FNode.Bank.GetActualTargetSecondsAverage(((CT_CalcNewTargetBlocksAverage DIV 4)*3))), - 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))]); - end else begin - isMining := false; - lblCurrentBlock.Caption := ''; - lblCurrentAccounts.Caption := ''; - lblCurrentBlockTime.Caption := ''; - lblOperationsPending.Caption := ''; - lblCurrentDifficulty.Caption := ''; - lblTimeAverage.Caption := ''; - lblTimeAverageAux.Caption := ''; - end; - if (Assigned(FPoolMiningServer)) And (FPoolMiningServer.Active) then begin - If FPoolMiningServer.ClientsCount>0 then begin - lblMinersClients.Caption := IntToStr(FPoolMiningServer.ClientsCount)+' connected JSON-RPC clients'; - lblMinersClients.Font.Color := clNavy; - end else begin - lblMinersClients.Caption := 'No JSON-RPC clients'; - lblMinersClients.Font.Color := clDkGray; - end; - MinersBlocksFound := FPoolMiningServer.ClientsWins; - end else begin - MinersBlocksFound := 0; - lblMinersClients.Caption := 'JSON-RPC server not active'; - lblMinersClients.Font.Color := clRed; - end; -end; - procedure TFRMWallet.UpdateConfigChanged(Sender:TObject); Var wa : Boolean; i : Integer; @@ -2565,7 +1141,7 @@ procedure TFRMWallet.UpdateConfigChanged(Sender:TObject); if (Not tsLogs.TabVisible) then begin FLog.OnNewLog := Nil; if PageControl.ActivePage = tsLogs then PageControl.ActivePage := tsMyAccounts; - end else FLog.OnNewLog := OnNewLog; + end else FLog.OnNewLog := FrameLogs.OnNewLog; if TSettings.SaveLogFiles then begin if TSettings.SaveDebugLogs then FLog.SaveTypes := CT_TLogTypes_ALL else FLog.SaveTypes := CT_TLogTypes_DEFAULT; @@ -2601,17 +1177,10 @@ procedure TFRMWallet.UpdateConfigChanged(Sender:TObject); i := Integer(TSettings.MinerPrivateKeyType); if (i>=Integer(Low(TMinerPrivateKeyType))) And (i<=Integer(High(TMinerPrivateKeyType))) then FMinerPrivateKeyType := TMinerPrivateKeyType(i) else FMinerPrivateKeyType := mpk_Random; - ebHashRateBackBlocks.Text := IntToStr(FBlockChainGrid.HashRateAverageBlocksCount); - Case FBlockChainGrid.HashRateAs of - hr_Unit : cbHashRateUnits.ItemIndex:=0; - hr_Kilo : cbHashRateUnits.ItemIndex:=1; - hr_Mega : cbHashRateUnits.ItemIndex:=2; - hr_Giga : cbHashRateUnits.ItemIndex:=3; - hr_Tera : cbHashRateUnits.ItemIndex:=4; - hr_Peta : cbHashRateUnits.ItemIndex:=5; - hr_Exa : cbHashRateUnits.ItemIndex:=6; - else cbHashRateUnits.ItemIndex:=-1; - end; + FrameBlockChainExplorer.ebHashRateBackBlocks.Text := IntToStr(FBlockChainGrid.HashRateAverageBlocksCount); + + FrameBlockChainExplorer.ChangeHashRateUnits( FBlockChainGrid.HashRateAs ); + if TNetData.NetDataExists then begin if TSettings.AppParams.ParamByName[CT_PARAM_AllowDownloadNewCheckpointIfOlderThan].GetAsBoolean(TNetData.NetData.MinFutureBlocksToDownloadNewSafebox>200) then begin TNetData.NetData.MinFutureBlocksToDownloadNewSafebox:=TSettings.AppParams.ParamByName[CT_PARAM_MinFutureBlocksToDownloadNewSafebox].GetAsInteger(TNetData.NetData.MinFutureBlocksToDownloadNewSafebox); @@ -2622,7 +1191,7 @@ procedure TFRMWallet.UpdateConfigChanged(Sender:TObject); procedure TFRMWallet.UpdateConnectionStatus; var errors : String; begin - UpdateNodeStatus; + FrameInfo.UpdateNodeStatus; OnNetStatisticsChanged(Nil); if Assigned(FNode) then begin if FNode.IsBlockChainValid(errors) then begin @@ -2636,81 +1205,13 @@ procedure TFRMWallet.UpdateConnectionStatus; end; end; -procedure TFRMWallet.UpdateNodeStatus; -Var status : String; -begin - If Not Assigned(FNode) then begin - lblNodeStatus.Font.Color := clRed; - lblNodeStatus.Caption := 'Initializing...'; - end else begin - If FNode.IsReady(status) then begin - if TNetData.NetData.NetStatistics.ActiveConnections>0 then begin - lblNodeStatus.Font.Color := clGreen; - if TNetData.NetData.IsDiscoveringServers then begin - lblNodeStatus.Caption := 'Discovering servers'; - end else if TNetData.NetData.IsGettingNewBlockChainFromClient(status) then begin - lblNodeStatus.Caption := 'Obtaining new blockchain '+status; - end else begin - lblNodeStatus.Caption := 'Running'; - end; - end else begin - lblNodeStatus.Font.Color := clRed; - lblNodeStatus.Caption := 'Alone in the world...'; - end; - end else begin - lblNodeStatus.Font.Color := clRed; - lblNodeStatus.Caption := status; - end; - end; - If Assigned(FBackgroundLabel) then begin - FBackgroundLabel.Font.Color:=lblNodeStatus.Font.Color; - FBackgroundLabel.Caption:='Please wait until finished: '+lblNodeStatus.Caption; - end; -end; - procedure TFRMWallet.UpdateOperations; Var accn : Int64; begin - accn := FAccountsGrid.AccountNumber(dgAccounts.Row); + accn := FrameAccountExplorer.AccountsGrid.AccountNumber(FrameAccountExplorer.dgAccounts.Row); FOperationsAccountGrid.AccountNumber := accn; end; -procedure TFRMWallet.UpdatePrivateKeys; -Var i,last_i : Integer; - wk : TWalletKey; - s : AnsiString; -begin - FNodeNotifyEvents.WatchKeys := FWalletKeys.AccountsKeyList; - if (cbMyPrivateKeys.ItemIndex>=0) then last_i := PtrInt(cbMyPrivateKeys.Items.Objects[cbMyPrivateKeys.ItemIndex]) - else last_i := -1; - cbMyPrivateKeys.items.BeginUpdate; - Try - cbMyPrivateKeys.Items.Clear; - For i:=0 to FWalletKeys.Count-1 do begin - wk := FWalletKeys.Key[i]; - if (wk.Name='') then begin - s := 'Sha256='+TCrypto.ToHexaString( TCrypto.DoSha256( TAccountComp.AccountKey2RawString(wk.AccountKey) ) ); - end else begin - s := wk.Name; - end; - if Not Assigned(wk.PrivateKey) then begin - if Length(wk.CryptedKey)>0 then s:=s+' (**NEED PASSWORD**)' - else s:=s+' (**PUBLIC KEY ONLY**)'; - end; - cbMyPrivateKeys.Items.AddObject(s,TObject(i)); - end; - cbMyPrivateKeys.Sorted := true; - cbMyPrivateKeys.Sorted := false; - cbMyPrivateKeys.Items.InsertObject(0,'(All my private keys)',TObject(-1)); - Finally - cbMyPrivateKeys.Items.EndUpdate; - End; - last_i := cbMyPrivateKeys.Items.IndexOfObject(TObject(last_i)); - if last_i<0 then last_i := 0; - if cbMyPrivateKeys.Items.Count>last_i then cbMyPrivateKeys.ItemIndex := last_i - else if cbMyPrivateKeys.Items.Count>=0 then cbMyPrivateKeys.ItemIndex := 0; -end; - initialization FRMWallet := Nil; end. diff --git a/src/gui-classic/UFRMWalletConfig.dfm b/src/gui-classic/UFRMWalletConfig.dfm new file mode 100644 index 000000000..d0ed34f56 --- /dev/null +++ b/src/gui-classic/UFRMWalletConfig.dfm @@ -0,0 +1,483 @@ +object FRMPascalCoinWalletConfig: TFRMPascalCoinWalletConfig + Left = 462 + Top = 234 + BorderIcons = [biSystemMenu] + BorderStyle = bsSingle + Caption = 'Options' + ClientHeight = 329 + ClientWidth = 475 + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + OldCreateOrder = True + Position = poOwnerFormCenter + OnCreate = FormCreate + PixelsPerInch = 96 + TextHeight = 13 + object Panel1: TPanel + Left = 0 + Top = 270 + Width = 475 + Height = 59 + Align = alBottom + Caption = ' ' + TabOrder = 0 + object bbOk: TBitBtn + Left = 16 + Top = 14 + Width = 75 + Height = 30 + Kind = bkOK + NumGlyphs = 2 + TabOrder = 0 + OnClick = bbOkClick + end + object bbCancel: TBitBtn + Left = 107 + Top = 14 + Width = 75 + Height = 30 + Kind = bkCancel + NumGlyphs = 2 + TabOrder = 1 + end + end + object PageControlWalletConfig: TPageControl + Left = 0 + Top = 0 + Width = 475 + Height = 270 + ActivePage = TabSheetPassword + Align = alClient + TabOrder = 1 + ExplicitWidth = 830 + ExplicitHeight = 392 + object TabSheetPassword: TTabSheet + Caption = 'Password' + object bbUpdatePassword: TBitBtn + Left = 15 + Top = 14 + Width = 337 + Height = 38 + Caption = 'Wallet Password' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -13 + Font.Name = 'Tahoma' + Font.Style = [fsBold] + Glyph.Data = { + 76060000424D7606000000000000360400002800000018000000180000000100 + 0800000000004002000000000000000000000001000000010000000000000101 + 0100020202000303030004040400050505000606060007070700080808000909 + 09000A0A0A000B0B0B000C0C0C000D0D0D000E0E0E000F0F0F00101010001111 + 1100121212001313130014141400151515001616160017171700181818001919 + 19001A1A1A001B1B1B001C1C1C001D1D1D001E1E1E001F1F1F00202020002121 + 2100222222002323230024242400252525002626260027272700282828002929 + 29002A2A2A002B2B2B002C2C2C002D2D2D002E2E2E002F2F2F00303030003131 + 3100323232003333330034343400353535003636360037373700383838003939 + 39003A3A3A003B3B3B003C3C3C003D3D3D003E3E3E003F3F3F00404040004141 + 4100424242004343430044444400454545004646460047474700484848004949 + 49004A4A4A004B4B4B004C4C4C004D4D4D004E4E4E004F4F4F00505050005151 + 5100525252005353530054545400555555005656560057575700585858005959 + 59005A5A5A005B5B5B005C5C5C005D5D5D005E5E5E00685968007C4F7C009441 + 9400B72CB700DD15DD00F506F500FD01FD00FE00FE00FE00FE00FE00FE00FE00 + FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00 + FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00 + FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00 + FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00 + FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00 + FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00 + FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00 + FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00 + FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00 + FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00 + FE00FE00FE00FE00FE00FE00FE00F008F900D517F000BD24E800A830E1007B4B + D0005065C1003774B7002B7DB100237FAC001F82AD001C83AD001785AE001687 + AF001489B100128AB300108CB6000F8EB9000D91BB000C94BF000A97C3000A99 + C5000A9AC7000B9BC8000B9CCA000C9ECC000C9FCD000DA0CE000DA1CE000EA2 + CF0011A3CF0015A4CF0018A5CF001CA7D10021A9D1002AAAD00035AACD0035AD + D00035AFD30035B1D60037B5D8003AB8DB003EB9DC0040BBDD0045BEDE004CC1 + E00055C6E3005BC8E40061CAE40066CBE3006BCCE30072D3E60078D8EB0080D8 + EE0083D9F10085DCF40088DBF5008BDBF6008EDAF70091DAF70095DCF70097E0 + F7009EE3F800A4E7F900A9E9F900AEE9F900B5EBF900B2EBF800919191919191 + 919191919191919191919191919191919191919191919191D5E7E8E7E3DED591 + 919191919191919191919191919191D6DDF7F8F8F7F6F4EEE6D5919191919191 + 919191919191D7DADEF8F8F6F7F6EDF1F8F1E69191919191919191919191DADE + DFFAFAF8F7F7E9EDF7F7F8EB91919191919191919191DDE5E3FCFCFAFAEEE0E9 + F3F7F7F7DC919191919191919191DEE7E4FEFEFCFCEDC5E0EFF7F6F6DC919191 + 919191919191DEEAE7FEFEFEFDFBC4C4F5F7F6F6DC919191919191919191E3EC + E9FEFEFEFEFEE0C3F9F7F6F6DC919191919191919191E3E9E3F8F8F1F1F8FBFB + FCFAF7F6DC919191919191919191DCEAEAE0E1E9E5E3DEE4EBF2FAF9DC919191 + 919191919191DBF3EEC5C5EFF3EBE5DDD9D6E6F5DC91919191919191919191D5 + E8EDF1FAF6F0EAE4DAD1D2DBDC919191919191919191919191DBE8F0F3F3F3E4 + D0CFE4D8DC919191919191919191919191919191D5DEE4DED2CFD4D491919191 + 91919191919191919191919191919191D2CE9191919191919191919191919191 + 91C8C89191919191D2CE919191919191919191919191919191D9D09191919191 + D2CE919191919191919191919191919191E6E39191919191D2CE919191919191 + 919191919191919191E0F3CE91919191D2CE9191919191919191919191919191 + 9191EFF6E1C9C8CDD9CC91919191919191919191919191919191C9EDF9F3F3EB + DC91919191919191919191919191919191919191CBE0E1CF9191919191919191 + 9191919191919191919191919191919191919191919191919191} + ParentFont = False + TabOrder = 0 + OnClick = bbUpdatePasswordClick + end + end + object TabSheetMiner: TTabSheet + Caption = 'Miner' + ImageIndex = 1 + object Label3: TLabel + Left = 15 + Top = 19 + Width = 82 + Height = 13 + Caption = 'Miner Name:' + Color = clBtnFace + ParentColor = False + end + object Label4: TLabel + Left = 103 + Top = 43 + Width = 298 + Height = 13 + Caption = 'This name will be included in each new block you mine!' + Color = clBtnFace + Font.Charset = ANSI_CHARSET + Font.Color = clGray + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Pitch = fpVariable + Font.Style = [] + Font.Quality = fqDraft + ParentColor = False + ParentFont = False + end + object lblDefaultInternetServerPort: TLabel + Left = 281 + Top = 72 + Width = 104 + Height = 13 + Caption = '(Default XXXX)' + Color = clBtnFace + ParentColor = False + end + object Label2: TLabel + Left = 15 + Top = 72 + Width = 182 + Height = 13 + Caption = 'Internet Server Port' + Color = clBtnFace + ParentColor = False + end + object ebMinerName: TEdit + Left = 103 + Top = 16 + Width = 298 + Height = 21 + TabOrder = 0 + Text = 'ebMinerName' + end + object ebInternetServerPort: TEdit + Left = 203 + Top = 69 + Width = 56 + Height = 21 + Alignment = taRightJustify + TabOrder = 1 + Text = '4004' + end + object udInternetServerPort: TUpDown + Left = 259 + Top = 69 + Width = 16 + Height = 21 + Associate = ebInternetServerPort + Min = 1 + Max = 25000 + Position = 4004 + TabOrder = 2 + Thousands = False + end + object gbMinerPrivateKey: TGroupBox + Left = 15 + Top = 104 + Width = 386 + Height = 121 + Caption = ' Miner Server Private Key: ' + TabOrder = 3 + object rbGenerateANewPrivateKeyEachBlock: TRadioButton + Left = 18 + Top = 22 + Width = 351 + Height = 19 + Caption = 'Generate a new private key for each generated block' + TabOrder = 0 + end + object rbUseARandomKey: TRadioButton + Left = 18 + Top = 42 + Width = 351 + Height = 19 + Caption = 'Use a random existing key' + TabOrder = 1 + end + object rbMineAllwaysWithThisKey: TRadioButton + Left = 18 + Top = 63 + Width = 351 + Height = 19 + Caption = 'Always mine with this key:' + TabOrder = 2 + end + object cbPrivateKeyToMine: TComboBox + Left = 35 + Top = 88 + Width = 334 + Height = 21 + Style = csDropDownList + TabOrder = 3 + end + end + end + object TabSheetJSON: TTabSheet + Caption = 'JSON' + ImageIndex = 2 + object Label7: TLabel + Left = 114 + Top = 68 + Width = 295 + Height = 13 + Caption = 'Ip'#39's separated by semicolon or empty for all' + Color = clBtnFace + Font.Charset = ANSI_CHARSET + Font.Color = clGray + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Pitch = fpVariable + Font.Style = [] + Font.Quality = fqDraft + ParentColor = False + ParentFont = False + end + object Label6: TLabel + Left = 24 + Top = 44 + Width = 84 + Height = 13 + Caption = 'Allowed IP'#39's' + Color = clBtnFace + ParentColor = False + end + object lblDefaultJSONRPCMinerServerPort: TLabel + Left = 248 + Top = 124 + Width = 70 + Height = 13 + Caption = '(Default XXXX)' + Color = clBtnFace + ParentColor = False + end + object Label5: TLabel + Left = 30 + Top = 124 + Width = 134 + Height = 13 + Caption = 'JSON-RPC Port' + Color = clBtnFace + ParentColor = False + end + object ebJSONRPCAllowedIPs: TEdit + Left = 114 + Top = 41 + Width = 295 + Height = 21 + TabOrder = 0 + Text = 'ebJSONRPCAllowedIPs' + end + object cbJSONRPCPortEnabled: TCheckBox + Left = 15 + Top = 16 + Width = 394 + Height = 19 + Caption = 'JSON-RPC Server port enabled (HTTP)' + TabOrder = 1 + OnClick = cbJSONRPCPortEnabledClick + end + object ebJSONRPCMinerServerPort: TEdit + Left = 170 + Top = 121 + Width = 56 + Height = 21 + Alignment = taRightJustify + TabOrder = 2 + Text = '4009' + end + object udJSONRPCMinerServerPort: TUpDown + Left = 226 + Top = 121 + Width = 16 + Height = 21 + Associate = ebJSONRPCMinerServerPort + Min = 1 + Max = 25000 + Position = 4009 + TabOrder = 3 + Thousands = False + end + object cbJSONRPCMinerServerActive: TCheckBox + Left = 15 + Top = 98 + Width = 402 + Height = 19 + Caption = 'JSON-RPC Server Miner (TCP/IP, no HTTP)' + TabOrder = 4 + end + end + object TabSheetBlockchain: TTabSheet + Caption = 'Blockchain' + ImageIndex = 3 + object ebMinFutureBlocksToDownloadNewSafebox: TEdit + Left = 352 + Top = 16 + Width = 53 + Height = 21 + Alignment = taRightJustify + TabOrder = 0 + Text = '0' + end + object cbDownloadNewCheckpoint: TCheckBox + Left = 15 + Top = 16 + Width = 330 + Height = 19 + Caption = 'Download new Checkpoint if blockchain older than...' + TabOrder = 1 + OnClick = cbDownloadNewCheckpointClick + end + end + object TabSheetOperations: TTabSheet + Caption = 'Operations' + ImageIndex = 4 + object Label1: TLabel + Left = 15 + Top = 19 + Width = 120 + Height = 13 + Caption = 'Default fee for operation' + Color = clBtnFace + ParentColor = False + end + object ebDefaultFee: TEdit + Left = 178 + Top = 16 + Width = 56 + Height = 21 + Alignment = taRightJustify + TabOrder = 0 + Text = '0' + end + end + object TabSheetLogs: TTabSheet + Caption = 'Logs' + ImageIndex = 5 + object cbSaveLogFiles: TCheckBox + Left = 15 + Top = 19 + Width = 78 + Height = 19 + Caption = 'Save log file' + TabOrder = 0 + OnClick = cbSaveLogFilesClick + end + object cbShowLogs: TCheckBox + Left = 15 + Top = 57 + Width = 68 + Height = 19 + Caption = 'Show logs' + TabOrder = 1 + end + object cbShowModalMessages: TCheckBox + Left = 15 + Top = 82 + Width = 127 + Height = 19 + Caption = 'Show modal messages' + TabOrder = 2 + end + object cbSaveDebugLogs: TCheckBox + Left = 31 + Top = 37 + Width = 118 + Height = 19 + Caption = 'Save debug logs too' + TabOrder = 3 + end + end + object TabSheetLanguage: TTabSheet + Caption = 'Language' + ImageIndex = 6 + object bbChangeLanguage: TBitBtn + Left = 15 + Top = 16 + Width = 131 + Height = 30 + Caption = 'Change UI language' + TabOrder = 0 + OnClick = bbChangeLanguageClick + end + end + object TabSheetStorage: TTabSheet + Caption = 'Storage' + ImageIndex = 7 + object bbOpenDataFolder: TBitBtn + Left = 15 + Top = 16 + Width = 131 + Height = 30 + Caption = 'Open Data Folder' + Glyph.Data = { + 36040000424D3604000000000000360000002800000010000000100000000100 + 2000000000000004000064000000640000000000000000000000078DBE4D078D + BEFF078DBEFF078DBEFF078DBEFF078DBEFF078DBEFF078DBEFF078DBEFF078D + BEFF078DBEFF078DBEFF078DBEFF078DBEFFFFFFFF00FFFFFF00078DBEFF25A1 + D1FF70C6E7FF6BCFF9FF66CDF9FF65CDF9FF65CDF9FF65CDF9FF65CDF8FF65CD + F9FF65CDF8FF66CEF9FF39ADD8FF078DBEFF078DBE4DFFFFFF00078DBEFF4CBC + E7FF5EB8DAFF94DFFBFF6FD4FAFF6FD4F9FF6ED4FAFF6FD4F9FF6FD4FAFF6FD4 + FAFF6FD4FAFF6ED4F9FF3EB1D9FF84D7EBFF078DBEFFFFFFFF00078DBEFF72D6 + FAFF1593C2FFB6ECFDFF7DDDFBFF79DCFBFF79DCFBFF79DCFBFF79DCFBFF7ADC + FBFF79DCFAFF79DCFAFF44B5D9FFAEF1F9FF078DBEFFFFFFFF00078DBEFF79DD + FBFF1899C7FF94DDF3FFA2EBFCFF84E4FBFF83E4FCFF83E4FCFF84E4FCFF83E4 + FCFF83E4FBFF84E5FCFF48B9DAFFB3F4F9FF078DBEFF078DBE4D078DBEFF82E3 + FCFF43B7DCFF4BB9DBFFBFF4FDFF8EEBFCFF8DEBFCFF8DEBFDFF8DEBFDFF8DEB + FCFF8DEBFDFF8DEBFCFF4CBBDAFFB6F7F9FF6DCAE0FF078DBEFF078DBEFF8AEA + FCFF77DCF3FF1496C3FFFFFFFFFFC9F8FEFFC9F8FEFFC9F8FEFFC9F8FFFFC9F7 + FFFFC9F8FEFFC9F8FFFF9CD6E7FFDFFAFBFFDBF7FAFF078DBEFF078DBEFF93F0 + FEFF93F0FDFF1697C5FF078DBEFF078DBEFF078DBEFF078DBEFF078DBEFF078D + BEFF078DBEFF078DBEFF078DBEFF078DBEFF078DBEFF078DBEFF078DBEFF9BF5 + FEFF9AF6FEFF9AF6FEFF9BF5FDFF9BF6FEFF9AF6FEFF9BF5FEFF9AF6FDFF9BF5 + FEFF9AF6FEFF9AF6FEFF0989BAFFFFFFFF00FFFFFF00FFFFFF00078DBEFFFEFE + FEFFA0FBFFFFA0FBFEFFA0FBFEFFA1FAFEFFA1FBFEFFA0FAFEFFA1FBFEFFA1FB + FFFFA0FBFFFFA1FBFFFF0989BAFFFFFFFF00FFFFFF00FFFFFF00078DBE4D078D + BEFFFEFEFEFFA5FEFFFFA5FEFFFFA5FEFFFF078DBEFF078DBEFF078DBEFF078D + BEFF078DBEFF078DBEFFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00078D + BE4D078DBEFF078DBEFF078DBEFF078DBEFF078DBE4DFFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00} + TabOrder = 0 + OnClick = bbOpenDataFolderClick + end + end + end +end diff --git a/src/gui-classic/UFRMPascalCoinWalletConfig.pas b/src/gui-classic/UFRMWalletConfig.pas similarity index 97% rename from src/gui-classic/UFRMPascalCoinWalletConfig.pas rename to src/gui-classic/UFRMWalletConfig.pas index 80f40a195..86cee5a11 100644 --- a/src/gui-classic/UFRMPascalCoinWalletConfig.pas +++ b/src/gui-classic/UFRMWalletConfig.pas @@ -1,4 +1,4 @@ -unit UFRMPascalCoinWalletConfig; +unit UFRMWalletConfig; { Copyright (c) 2016 by Albert Molina @@ -30,7 +30,8 @@ interface LCLIntf, LCLType, LMessages, {$ENDIF} Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, - Dialogs, StdCtrls, Buttons, ComCtrls, UAppParams, USettings, UWallet; + Dialogs, StdCtrls, Buttons, ComCtrls, UAppParams, USettings, UWallet, + Vcl.ExtCtrls; type @@ -38,40 +39,50 @@ interface { TFRMPascalCoinWalletConfig } TFRMPascalCoinWalletConfig = class(TForm) - bbChangeLanguage: TBitBtn; + Panel1: TPanel; + PageControlWalletConfig: TPageControl; + TabSheetMiner: TTabSheet; + TabSheetPassword: TTabSheet; + TabSheetJSON: TTabSheet; + Label7: TLabel; + Label6: TLabel; + lblDefaultJSONRPCMinerServerPort: TLabel; + Label5: TLabel; + ebJSONRPCAllowedIPs: TEdit; + cbJSONRPCPortEnabled: TCheckBox; + ebJSONRPCMinerServerPort: TEdit; + udJSONRPCMinerServerPort: TUpDown; cbJSONRPCMinerServerActive: TCheckBox; - cbDownloadNewCheckpoint: TCheckBox; - ebDefaultFee: TEdit; + TabSheetBlockchain: TTabSheet; ebMinFutureBlocksToDownloadNewSafebox: TEdit; + cbDownloadNewCheckpoint: TCheckBox; + TabSheetOperations: TTabSheet; Label1: TLabel; + ebDefaultFee: TEdit; + TabSheetLogs: TTabSheet; cbSaveLogFiles: TCheckBox; cbShowLogs: TCheckBox; - bbOk: TBitBtn; - bbCancel: TBitBtn; - udInternetServerPort: TUpDown; - ebInternetServerPort: TEdit; - Label2: TLabel; - lblDefaultInternetServerPort: TLabel; - bbUpdatePassword: TBitBtn; + cbShowModalMessages: TCheckBox; + cbSaveDebugLogs: TCheckBox; + TabSheetLanguage: TTabSheet; + bbChangeLanguage: TBitBtn; + TabSheetStorage: TTabSheet; + bbOpenDataFolder: TBitBtn; Label3: TLabel; - ebMinerName: TEdit; Label4: TLabel; - cbShowModalMessages: TCheckBox; - Label5: TLabel; - udJSONRPCMinerServerPort: TUpDown; - ebJSONRPCMinerServerPort: TEdit; - lblDefaultJSONRPCMinerServerPort: TLabel; + lblDefaultInternetServerPort: TLabel; + Label2: TLabel; + ebMinerName: TEdit; + ebInternetServerPort: TEdit; + udInternetServerPort: TUpDown; gbMinerPrivateKey: TGroupBox; rbGenerateANewPrivateKeyEachBlock: TRadioButton; rbUseARandomKey: TRadioButton; rbMineAllwaysWithThisKey: TRadioButton; cbPrivateKeyToMine: TComboBox; - cbSaveDebugLogs: TCheckBox; - bbOpenDataFolder: TBitBtn; - cbJSONRPCPortEnabled: TCheckBox; - ebJSONRPCAllowedIPs: TEdit; - Label6: TLabel; - Label7: TLabel; + bbUpdatePassword: TBitBtn; + bbOk: TBitBtn; + bbCancel: TBitBtn; procedure bbChangeLanguageClick(Sender: TObject); procedure cbDownloadNewCheckpointClick(Sender: TObject); procedure FormCreate(Sender: TObject); diff --git a/src/gui-classic/UFRMWalletInformation.pas b/src/gui-classic/UFRMWalletInformation.pas new file mode 100644 index 000000000..214ea5050 --- /dev/null +++ b/src/gui-classic/UFRMWalletInformation.pas @@ -0,0 +1,186 @@ +unit UFRMWalletInformation; + +interface + +uses + UFRMWallet, Classes, UBlockChain; + +type + TFRMWalletInformation = class + private + + public + class procedure FillAccountInformation + ( + const Strings: TStrings; + const AccountNumber: Cardinal + ); + + class procedure FillOperationInformation + ( + const Strings: TStrings; + const OperationResume: TOperationResume + ); + end; + +implementation + +uses + UPCDataTypes, UJSONFunctions, SysUtils, UAccounts, UBaseTypes, URPC, + UEPasa, UTxMultiOperation, UCrypto, UEPasaDecoder; + +class procedure TFRMWalletInformation.FillAccountInformation +( + const Strings: TStrings; + const AccountNumber: Cardinal +); +Var + account : TAccount; + s : String; + LjsonObj : TPCJSONObject; + vString : string; +begin + if AccountNumber<0 then exit; + account := FRMWallet.Node.GetMempoolAccount(AccountNumber); + if + Length(account.name)>0 then + s:='Name: '+TEncoding.ANSI.GetString(account.name) + else + s:=''; + Strings.Add(Format('Account: %s %s Type:%d',[TAccountComp.AccountNumberToAccountTxtNumber(AccountNumber),s,account.account_type])); + Strings.Add(''); + Strings.Add(Format('Current balance: %s',[TAccountComp.FormatMoney(account.balance)])); + Strings.Add(''); + Strings.Add(Format('Updated on block: %d (%d blocks ago)',[account.GetLastUpdatedBlock,FRMWallet.Node.Bank.BlocksCount-account.GetLastUpdatedBlock])); + Strings.Add(Format('Updated on block as active mode: %d (%d blocks ago)',[account.updated_on_block_active_mode,FRMWallet.Node.Bank.BlocksCount-account.updated_on_block_active_mode])); + Strings.Add(Format('Public key type: %s',[TAccountComp.GetECInfoTxt(account.accountInfo.accountKey.EC_OpenSSL_NID)])); + Strings.Add(Format('Base58 Public key: %s',[TAccountComp.AccountPublicKeyExport(account.accountInfo.accountKey)])); + + if Length(account.account_data)>0 then + begin + // Skybuck: string compilation fail: needs UBaseTypes otherwise don't compile. + vString := account.account_data.ToHexaString; + Strings.Add + ( + Format + ( + 'Account Data: %s', + [ + vString + ] + ) + ) + end else Strings.Add(Format('Account Data: (No data)',[])); + Strings.Add(Format('Account Seal: %s',[account.account_seal.ToHexaString])); + if TAccountComp.IsAccountForSale(account.accountInfo) then begin + Strings.Add(''); + Strings.Add('** Account is for sale: **'); + Strings.Add(Format('Price: %s',[TAccountComp.FormatMoney(account.accountInfo.price)])); + Strings.Add(Format('Seller account (where to pay): %s',[TAccountComp.AccountNumberToAccountTxtNumber(account.accountInfo.account_to_pay)])); + if TAccountComp.IsAccountForPrivateSale(account.accountInfo) then begin + Strings.Add(''); + Strings.Add('** Private sale **'); + Strings.Add(Format('New Base58 Public key: %s',[TAccountComp.AccountPublicKeyExport(account.accountInfo.new_publicKey)])); + Strings.Add(''); + if TAccountComp.IsAccountLocked(account.accountInfo,FRMWallet.Node.Bank.BlocksCount) then begin + Strings.Add(Format('PURCHASE IS SECURE UNTIL BLOCK %d (current %d, remains %d)', + [account.accountInfo.locked_until_block,FRMWallet.Node.Bank.BlocksCount,account.accountInfo.locked_until_block-FRMWallet.Node.Bank.BlocksCount])); + end else begin + Strings.Add(Format('PURCHASE IS NOT SECURE (Expired on block %d, current %d)', + [account.accountInfo.locked_until_block,FRMWallet.Node.Bank.BlocksCount])); + end; + end; + end else if TAccountComp.IsAccountForSwap(account.accountInfo) then begin + Strings.Add(''); + if TAccountComp.IsAccountForAccountSwap(account.accountInfo) then begin + Strings.Add('** Account is for Atomic Account Swap: **'); + Strings.Add(Format('New Base58 Public key: %s',[TAccountComp.AccountPublicKeyExport(account.accountInfo.new_publicKey)])); + end else if TAccountComp.IsAccountForCoinSwap(account.accountInfo) then begin + Strings.Add('** Account is for Atomic Coin Swap: **'); + Strings.Add(Format('Amount to swap: %s',[TAccountComp.FormatMoney(account.accountInfo.price)])); + Strings.Add(Format('Counterparty account: %s',[TAccountComp.AccountNumberToAccountTxtNumber(account.accountInfo.account_to_pay)])); + end; + Strings.Add(Format('Public secret to find: %s',[account.accountInfo.hashed_secret.ToHexaString])); + Strings.Add(''); + if TAccountComp.IsAccountLocked(account.accountInfo,FRMWallet.Node.Bank.BlocksCount) then begin + Strings.Add(Format('SWAP IS SECURE UNTIL BLOCK %d (current %d, remains %d)', + [account.accountInfo.locked_until_block,FRMWallet.Node.Bank.BlocksCount,account.accountInfo.locked_until_block-FRMWallet.Node.Bank.BlocksCount])); + end else begin + Strings.Add(Format('SWAP IS NOT SECURE (Expired on block %d, current %d)', + [account.accountInfo.locked_until_block,FRMWallet.Node.Bank.BlocksCount])); + end; + end; + LjsonObj := TPCJSONObject.Create; + Try + TPascalCoinJSONComp.FillAccountObject(account,LjsonObj); + Strings.Add('ACCOUNT JSON:'); + Strings.Add(LjsonObj.ToJSON(False)); + Finally + LjsonObj.Free; + end; + +end; + +class procedure TFRMWalletInformation.FillOperationInformation +( + const Strings: TStrings; + const OperationResume: TOperationResume +); +var i : Integer; + jsonObj : TPCJSONObject; + LEPASA : TEPasa; +begin + If (not OperationResume.valid) then exit; + If OperationResume.Block=0) then begin + Strings.Add(Format('Block: %d/%d',[OperationResume.Block,OperationResume.NOpInsideBlock])) + end else begin + Strings.Add(Format('Block: %d',[OperationResume.Block])) + end + else Strings.Add('** Pending operation not included on blockchain **'); + Strings.Add(Format('%s',[OperationResume.OperationTxt])); + If (OperationResume.isMultiOperation) then begin + Strings.Add('Multioperation:'); + For i := 0 to High(OperationResume.Senders) do begin + Strings.Add(Format(' Sender (%d/%d): %s %s PASC Payload(%d):%s',[i+1,length(OperationResume.Senders),TAccountComp.AccountNumberToAccountTxtNumber(OperationResume.Senders[i].Account),TAccountComp.FormatMoney(OperationResume.Senders[i].Amount),OperationResume.Senders[i].Payload.payload_type,OperationResume.Senders[i].Payload.payload_raw.ToHexaString])); + end; + For i := 0 to High(OperationResume.Receivers) do begin + Strings.Add(Format(' Receiver (%d/%d): %s %s PASC Payload(%d):%s',[i+1,length(OperationResume.Receivers),TAccountComp.AccountNumberToAccountTxtNumber(OperationResume.Receivers[i].Account),TAccountComp.FormatMoney(OperationResume.Receivers[i].Amount),OperationResume.Receivers[i].Payload.payload_type,OperationResume.Receivers[i].Payload.payload_raw.ToHexaString])); + end; + For i := 0 to High(OperationResume.Changers) do begin + Strings.Add(Format(' Change info (%d/%d): %s [%s]',[i+1,length(OperationResume.Changers),TAccountComp.AccountNumberToAccountTxtNumber(OperationResume.Changers[i].Account),TOpMultiOperation.OpChangeAccountInfoTypesToText(OperationResume.Changers[i].Changes_type)])); + end; + + end; + Strings.Add(Format('OpType:%d Subtype:%d',[OperationResume.OpType,OperationResume.OpSubtype])); + Strings.Add(Format('Operation Hash (ophash): %s',[TCrypto.ToHexaString(OperationResume.OperationHash)])); + If (Length(OperationResume.OperationHash_OLD)>0) then begin + Strings.Add(Format('Old Operation Hash (old_ophash): %s',[TCrypto.ToHexaString(OperationResume.OperationHash_OLD)])); + end; + if TEPasaDecoder.TryDecodeEPASA(OperationResume.DestAccount,OperationResume.OriginalPayload,FRMWallet.Node,FRMWallet.WalletKeys,Nil,LEPASA) then begin + Strings.Add('EPASA: '+LEPASA.ToString); + end else Strings.Add('No EPASA format'); + Strings.Add(Format('Payload type:%s length:%d',['0x'+IntToHex(OperationResume.OriginalPayload.payload_type,2), length(OperationResume.OriginalPayload.payload_raw)])); + if (Length(OperationResume.OriginalPayload.payload_raw)>0) then begin + If OperationResume.PrintablePayload<>'' then begin + Strings.Add(Format('Payload (human): %s',[OperationResume.PrintablePayload])); + end; + Strings.Add(Format('Payload (Hexadecimal): %s',[TCrypto.ToHexaString(OperationResume.OriginalPayload.payload_raw)])); + end; + If OperationResume.Balance>=0 then begin + Strings.Add(Format('Final balance: %s',[TAccountComp.FormatMoney(OperationResume.Balance)])); + end; + jsonObj := TPCJSONObject.Create; + Try + TPascalCoinJSONComp.FillOperationObject(OperationResume,FRMWallet.Node.Bank.BlocksCount, + FRMWallet.Node,FRMWallet.WalletKeys,Nil, + jsonObj); + Strings.Add('OPERATION JSON:'); + Strings.Add(jsonObj.ToJSON(False)); + Finally + jsonObj.Free; + end; +end; + + +end. diff --git a/src/gui-classic/UFRMWalletUserMessages.pas b/src/gui-classic/UFRMWalletUserMessages.pas new file mode 100644 index 000000000..b458b3029 --- /dev/null +++ b/src/gui-classic/UFRMWalletUserMessages.pas @@ -0,0 +1,18 @@ +unit UFRMWalletUserMessages; + +interface + +uses +{$IFnDEF FPC} + Messages +{$ELSE} + LMessages +{$ENDIF}; + +Const + CM_PC_WalletKeysChanged = WM_USER + 1; + CM_PC_NetConnectionUpdated = WM_USER + 2; + +implementation + +end. diff --git a/src/gui-classic/UnitReIntegrate.pas b/src/gui-classic/UnitReIntegrate.pas new file mode 100644 index 000000000..617125dfd --- /dev/null +++ b/src/gui-classic/UnitReIntegrate.pas @@ -0,0 +1,15 @@ +unit UnitReIntegrate; + +interface + + + +implementation + + + + + + + +end. diff --git a/src/pascalcoin_wallet_classic.dpr b/src/pascalcoin_wallet_classic.dpr index 993614b1e..cc3d1421b 100644 --- a/src/pascalcoin_wallet_classic.dpr +++ b/src/pascalcoin_wallet_classic.dpr @@ -25,7 +25,7 @@ uses {$IFDEF USE_GNUGETTEXT} UFRMSelectLanguage in 'gui-classic\UFRMSelectLanguage.pas' {FRMChangeLanguage}, {$ENDIF } - UFRMPascalCoinWalletConfig in 'gui-classic\UFRMPascalCoinWalletConfig.pas' {FRMPascalCoinWalletConfig}, + UFRMWalletConfig in 'gui-classic\UFRMWalletConfig.pas' {FRMPascalCoinWalletConfig}, UFRMPayloadDecoder in 'gui-classic\UFRMPayloadDecoder.pas' {FRMPayloadDecoder}, UFRMRandomOperations in 'gui-classic\UFRMRandomOperations.pas' {FRMRandomOperations}, UFRMRPCCalls in 'gui-classic\UFRMRPCCalls.pas' {FRMRPCCalls}, @@ -58,8 +58,7 @@ uses UOpTransaction in 'core\UOpTransaction.pas', {$IFDEF USE_ABSTRACTMEM} UPCAbstractMem in 'core\UPCAbstractMem.pas', - UPCAbstractMemAccountKeys in 'core\UPCAbstractMemAccountKeys.pas', - {$ENDIF} + {$ENDIF } UPCAbstractMemAccounts in 'core\UPCAbstractMemAccounts.pas', UPCAccountsOrdenations in 'core\UPCAccountsOrdenations.pas', UPCCryptoLib4Pascal in 'core\UPCCryptoLib4Pascal.pas', @@ -89,7 +88,21 @@ uses UThread in 'core\UThread.pas', UTime in 'core\UTime.pas', UTxMultiOperation in 'core\UTxMultiOperation.pas', - UWallet in 'core\UWallet.pas'; + UWallet in 'core\UWallet.pas', + UFrameAccountExplorer in 'gui-classic\Frames\UFrameAccountExplorer.pas' {FrameAccountExplorer: TFrame}, + UFramePendingOperations in 'gui-classic\Frames\UFramePendingOperations.pas' {FramePendingOperations: TFrame}, + UFrameBlockExplorer in 'gui-classic\Frames\UFrameBlockExplorer.pas' {FrameBlockChainExplorer: TFrame}, + UFrameOperationsExplorer in 'gui-classic\Frames\UFrameOperationsExplorer.pas' {FrameOperationsExplorer: TFrame}, + UFrameLogs in 'gui-classic\Frames\UFrameLogs.pas' {FrameLogs: TFrame}, + UFrameNodeStats in 'gui-classic\Frames\UFrameNodeStats.pas' {FrameNodeStats: TFrame}, + UFrameMessages in 'gui-classic\Frames\UFrameMessages.pas' {FrameMessages: TFrame}, + UnitReIntegrate in 'gui-classic\UnitReIntegrate.pas', + UFRMTestWallet in 'gui-classic\UFRMTestWallet.pas' {FRMTestWallet}, + UFrameInfo in 'gui-classic\Frames\UFrameInfo.pas' {FrameInfo: TFrame}, + UFRMWalletUserMessages in 'gui-classic\UFRMWalletUserMessages.pas', + UFRMWalletInformation in 'gui-classic\UFRMWalletInformation.pas', + UJSONFunctions in 'libraries\pascalcoin\UJSONFunctions.pas', + UEPasaDecoder in 'core\UEPasaDecoder.pas'; {$R *.res} @@ -97,6 +110,11 @@ begin Application.Initialize; {$IFDEF WINDOWS}Application.MainFormOnTaskbar := True;{$ENDIF} Application.Title := 'Pascal Coin Wallet, Miner & Explorer'; + + {$IFDEF TESTNET} + Application.CreateForm(TFRMTestWallet, FRMTestWallet); + {$ELSE} Application.CreateForm(TFRMWallet, FRMWallet); + {$ENDIF} Application.Run; end. diff --git a/src/pascalcoin_wallet_classic.dproj b/src/pascalcoin_wallet_classic.dproj index 1f1d7ae67..a172e9dab 100644 --- a/src/pascalcoin_wallet_classic.dproj +++ b/src/pascalcoin_wallet_classic.dproj @@ -7,7 +7,7 @@ 3 Application VCL - 18.8 + 19.2 Win32 @@ -156,7 +156,7 @@
FRMChangeLanguage
- +
FRMPascalCoinWalletConfig
@@ -204,7 +204,6 @@ - @@ -235,6 +234,56 @@ + +
FrameAccountExplorer
+ dfm + TFrame +
+ +
FramePendingOperations
+ dfm + TFrame +
+ +
FrameBlockChainExplorer
+ dfm + TFrame +
+ +
FrameOperationsExplorer
+ dfm + TFrame +
+ +
FrameLogs
+ dfm + TFrame +
+ +
FrameNodeStats
+ dfm + TFrame +
+ +
FrameMessages
+ dfm + TFrame +
+ + +
FRMTestWallet
+ dfm +
+ +
FrameInfo
+ dfm + TFrame +
+ + + + + Cfg_2 Base @@ -272,6 +321,12 @@ true + + + .\ + true + + 1 @@ -412,6 +467,16 @@ 1 + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + res\drawable-ldpi @@ -663,6 +728,32 @@ 0 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + 1 @@ -762,6 +853,16 @@ 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + 1 @@ -773,6 +874,66 @@ 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + 1 @@ -872,6 +1033,16 @@ 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + 1 @@ -883,6 +1054,16 @@ 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + 1 @@ -927,6 +1108,86 @@ 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + 1 @@ -974,6 +1235,16 @@ 1 + + + ..\$(PROJECTNAME).launchscreen + 64 + + + ..\$(PROJECTNAME).launchscreen + 64 + + 1 diff --git a/src/pascalcoin_wallet_classic.res b/src/pascalcoin_wallet_classic.res index 1450bc9f9..0a9b51d2e 100644 Binary files a/src/pascalcoin_wallet_classic.res and b/src/pascalcoin_wallet_classic.res differ