/// <summary>
        ///     Load transMethodInvoker in cache.
        /// </summary>
        /// <param name="walletAddress"></param>
        /// <returns></returns>
        public static void LoadWalletCache(string walletAddress)
        {
            if (ListTransaction != null)
            {
                ListTransaction.Clear();
            }
            else
            {
                ListTransaction = new Dictionary <string, ClassWalletTransactionObject>();
            }
            if (!string.IsNullOrEmpty(walletAddress))
            {
                OnLoad = true;
                try
                {
                    Task.Factory.StartNew(() =>
                    {
                        if (Directory.Exists(
                                ClassUtility.ConvertPath(AppDomain.CurrentDomain.BaseDirectory +
                                                         WalletTransMethodInvokerCacheDirectory + walletAddress +
                                                         "\\")))
                        {
                            if (File.Exists(ClassUtility.ConvertPath(
                                                AppDomain.CurrentDomain.BaseDirectory + WalletTransMethodInvokerCacheDirectory +
                                                walletAddress + "\\" + WalletTransMethodInvokerCacheFileExtension)))
                            {
                                byte[] AesKeyIv = null;
                                byte[] AesSalt  = null;
                                using (var password = new PasswordDeriveBytes(
                                           Program.WalletXiropht.ClassWalletObject.WalletConnect.WalletAddress +
                                           Program.WalletXiropht.ClassWalletObject.WalletConnect.WalletKey,
                                           ClassUtils.GetByteArrayFromString(ClassUtils.FromHex(
                                                                                 (Program.WalletXiropht.ClassWalletObject.WalletConnect.WalletAddress +
                                                                                  Program.WalletXiropht.ClassWalletObject.WalletConnect.WalletKey)
                                                                                 .Substring(0, 8)))))
                                {
                                    AesKeyIv = password.GetBytes(
                                        ClassConnectorSetting.MAJOR_UPDATE_1_SECURITY_CERTIFICATE_SIZE / 8);
                                    AesSalt = password.GetBytes(16);
                                }

                                var listTransactionEncrypted = new List <string>();
                                using (var fs = File.Open(
                                           ClassUtility.ConvertPath(AppDomain.CurrentDomain.BaseDirectory +
                                                                    WalletTransMethodInvokerCacheDirectory +
                                                                    walletAddress +
                                                                    "\\" + WalletTransMethodInvokerCacheFileExtension),
                                           FileMode.Open, FileAccess.Read, FileShare.Read))
                                    using (var bs = new BufferedStream(fs))
                                        using (var sr = new StreamReader(bs))
                                        {
                                            string line;
                                            while ((line = sr.ReadLine()) != null)
                                            {
                                                listTransactionEncrypted.Add(line);
                                            }
                                        }

                                if (listTransactionEncrypted.Count > 0)
                                {
                                    var line = 0;
                                    foreach (var transactionEncrypted in listTransactionEncrypted)
                                    {
                                        line++;
                                        var walletTransactionDecrypted =
                                            ClassAlgo.GetDecryptedResult(ClassAlgoEnumeration.Rijndael,
                                                                         transactionEncrypted, ClassWalletNetworkSetting.KeySize, AesKeyIv,
                                                                         AesSalt);
                                        if (walletTransactionDecrypted != ClassAlgoErrorEnumeration.AlgoError)
                                        {
                                            var splitTransaction =
                                                walletTransactionDecrypted.Split(new[] { "#" },
                                                                                 StringSplitOptions.None);
                                            if (!ListTransaction.ContainsKey(splitTransaction[1]))
                                            {
                                                var splitBlockchainHeight = splitTransaction[7]
                                                                            .Split(new[] { "~" }, StringSplitOptions.None);

                                                var transactionObject = new ClassWalletTransactionObject
                                                {
                                                    TransactionType          = splitTransaction[0],
                                                    TransactionHash          = splitTransaction[1],
                                                    TransactionWalletAddress = splitTransaction[2],
                                                    TransactionAmount        =
                                                        decimal.Parse(
                                                            splitTransaction[3].ToString(Program.GlobalCultureInfo),
                                                            NumberStyles.Currency, Program.GlobalCultureInfo),
                                                    TransactionFee = decimal.Parse(
                                                        splitTransaction[4].ToString(Program.GlobalCultureInfo),
                                                        NumberStyles.Currency, Program.GlobalCultureInfo),
                                                    TransactionTimestampSend    = long.Parse(splitTransaction[5]),
                                                    TransactionTimestampRecv    = long.Parse(splitTransaction[6]),
                                                    TransactionBlockchainHeight =
                                                        splitBlockchainHeight[0].Replace("{", "")
                                                };
                                                ListTransaction.Add(splitTransaction[1], transactionObject);

                                                Program.WalletXiropht.UpdateLabelSyncInformation(
                                                    "On load transaction database - total transactions loaded and decrypted: " +
                                                    (ListTransaction.Count + ClassWalletTransactionAnonymityCache
                                                     .ListTransaction.Count));
                                            }
#if DEBUG
                                            else
                                            {
                                                Log.WriteLine("Duplicate anonymous transaction: " + walletTransactionDecrypted);
                                            }
#endif
                                        }

#if DEBUG
                                        else
                                        {
                                            Log.WriteLine("Wrong transaction at line: " + line);
                                        }
#endif
                                    }
                                }

                                listTransactionEncrypted.Clear();
                                Program.WalletXiropht.ClassWalletObject.TotalTransactionInSync =
                                    ListTransaction.Count;
                                AesKeyIv = null;
                                AesSalt  = null;
                            }
                            else
                            {
                                File.Create(ClassUtility.ConvertPath(
                                                AppDomain.CurrentDomain.BaseDirectory + WalletTransMethodInvokerCacheDirectory +
                                                walletAddress + "\\" + WalletTransMethodInvokerCacheFileExtension)).Close();
                            }
                        }
                        else
                        {
                            if (Directory.Exists(ClassUtility.ConvertPath(
                                                     AppDomain.CurrentDomain.BaseDirectory +
                                                     WalletTransMethodInvokerCacheDirectory)) ==
                                false)
                            {
                                Directory.CreateDirectory(ClassUtility.ConvertPath(
                                                              AppDomain.CurrentDomain.BaseDirectory +
                                                              WalletTransMethodInvokerCacheDirectory));
                            }

                            Directory.CreateDirectory(ClassUtility.ConvertPath(
                                                          AppDomain.CurrentDomain.BaseDirectory + WalletTransMethodInvokerCacheDirectory +
                                                          walletAddress));
                        }

                        Program.WalletXiropht.ClassWalletObject.TotalTransactionInSync = ListTransaction.Count;
                        OnLoad = false;
                    }, Program.WalletXiropht.WalletCancellationToken.Token,
                                          TaskCreationOptions.DenyChildAttach, TaskScheduler.Current).ConfigureAwait(false);
                }
                catch
                {
                    Program.WalletXiropht.ClassWalletObject.TotalTransactionInSync = 0;
                    ListTransaction.Clear();
                    OnLoad = false;
                }
            }
        }
        /// <summary>
        ///     Add transaction to the list.
        /// </summary>
        /// <param name="transaction"></param>
        /// <param name="node"></param>
        public static async Task AddWalletTransactionAsync(string transaction, string node)
        {
#if DEBUG
            Log.WriteLine("Wallet transaction history received: " + transaction
                          .Replace(
                              ClassRemoteNodeCommandForWallet.RemoteNodeRecvPacketEnumeration
                              .WalletTransactionPerId, ""));
#endif
            bool errorSyncTransaction = false;

            if (!OnLoad)
            {
                var splitTransaction = transaction
                                       .Replace(ClassRemoteNodeCommandForWallet.RemoteNodeRecvPacketEnumeration.WalletTransactionPerId,
                                                string.Empty).Split(new[] { "#" }, StringSplitOptions.None);
                var hashTransaction = splitTransaction[4]; // Transaction Hash.
                if (!ListTransaction.ContainsKey(hashTransaction))
                {
                    var type              = splitTransaction[0];
                    var timestamp         = splitTransaction[3]; // Timestamp Send CEST.
                    var realFeeAmountSend = splitTransaction[7]; // Real fee and amount crypted for sender.
                    var realFeeAmountRecv = splitTransaction[8]; // Real fee and amount crypted for sender.

                    var amountAndFeeDecrypted = ClassAlgoErrorEnumeration.AlgoError;
                    if (type == "SEND")
                    {
                        amountAndFeeDecrypted = ClassAlgo.GetDecryptedResultManual(ClassAlgoEnumeration.Rijndael,
                                                                                   realFeeAmountSend,
                                                                                   Program.WalletXiropht.ClassWalletObject.WalletConnect.WalletAddress +
                                                                                   Program.WalletXiropht.ClassWalletObject.WalletConnect.WalletKey,
                                                                                   ClassWalletNetworkSetting.KeySize); // AES
                    }
                    else if (type == "RECV")
                    {
                        amountAndFeeDecrypted = ClassAlgo.GetDecryptedResultManual(ClassAlgoEnumeration.Rijndael,
                                                                                   realFeeAmountRecv,
                                                                                   Program.WalletXiropht.ClassWalletObject.WalletConnect.WalletAddress +
                                                                                   Program.WalletXiropht.ClassWalletObject.WalletConnect.WalletKey,
                                                                                   ClassWalletNetworkSetting.KeySize); // AES
                    }
                    if (amountAndFeeDecrypted != ClassAlgoErrorEnumeration.AlgoError)
                    {
                        var splitDecryptedAmountAndFee =
                            amountAndFeeDecrypted.Split(new[] { "-" }, StringSplitOptions.None);
                        var amountDecrypted = splitDecryptedAmountAndFee[0];
                        var feeDecrypted    = splitDecryptedAmountAndFee[1];
                        var walletDstOrSrc  = splitDecryptedAmountAndFee[2];


                        var timestampRecv    = splitTransaction[5]; // Timestamp Recv CEST.
                        var blockchainHeight = splitTransaction[6]; // Blockchain height.

                        var finalTransaction = type + "#" + hashTransaction + "#" + walletDstOrSrc + "#" +
                                               amountDecrypted + "#" + feeDecrypted + "#" + timestamp + "#" +
                                               timestampRecv + "#" + blockchainHeight;

                        var finalTransactionEncrypted = ClassAlgo.GetEncryptedResultManual(
                            ClassAlgoEnumeration.Rijndael, finalTransaction,
                            Program.WalletXiropht.ClassWalletObject.WalletConnect.WalletAddress +
                            Program.WalletXiropht.ClassWalletObject.WalletConnect.WalletKey,
                            ClassWalletNetworkSetting.KeySize);                               // AES

                        if (finalTransactionEncrypted == ClassAlgoErrorEnumeration.AlgoError) // Ban bad remote node.
                        {
                            errorSyncTransaction = true;
                        }
                        else
                        {
                            var splitBlockchainHeight = blockchainHeight.Split(new[] { "~" }, StringSplitOptions.None);

                            var transactionObject = new ClassWalletTransactionObject
                            {
                                TransactionType          = type,
                                TransactionHash          = hashTransaction,
                                TransactionWalletAddress = walletDstOrSrc,
                                TransactionAmount        = decimal.Parse(amountDecrypted.ToString(Program.GlobalCultureInfo),
                                                                         NumberStyles.Currency, Program.GlobalCultureInfo),
                                TransactionFee = decimal.Parse(feeDecrypted.ToString(Program.GlobalCultureInfo),
                                                               NumberStyles.Currency, Program.GlobalCultureInfo),
                                TransactionTimestampSend    = long.Parse(timestamp),
                                TransactionTimestampRecv    = long.Parse(timestampRecv),
                                TransactionBlockchainHeight = splitBlockchainHeight[0].Replace("{", "")
                            };

                            ListTransaction.Add(hashTransaction, transactionObject);


                            await SaveWalletCache(Program.WalletXiropht.ClassWalletObject.WalletConnect.WalletAddress, finalTransactionEncrypted);

#if DEBUG
                            Log.WriteLine("Total transactions downloaded: " +
                                          ListTransaction.Count + "/" +
                                          Program.WalletXiropht.ClassWalletObject.TotalTransactionInSync + ".");
#endif
                        }
                    }
                    else
                    {
#if DEBUG
                        Log.WriteLine("Can't decrypt transaction: " + transaction + " result: " +
                                      amountAndFeeDecrypted);
#endif
                        errorSyncTransaction = true;
                    }
                }
                else
                {
#if DEBUG
                    Log.WriteLine("Wallet transaction hash: " + hashTransaction + " already exist on database.");
#endif
                    errorSyncTransaction = true;
                }
            }

            if (errorSyncTransaction)
            {
                if (!ClassConnectorSetting.SeedNodeIp.ContainsKey(node))
                {
                    if (!Program.WalletXiropht.ClassWalletObject.ListRemoteNodeBanned.ContainsKey(node))
                    {
                        Program.WalletXiropht.ClassWalletObject.ListRemoteNodeBanned.Add(node,
                                                                                         ClassUtils.DateUnixTimeNowSecond());
                        ClassPeerList.IncrementPeerDisconnect(node);
                    }
                    else
                    {
                        Program.WalletXiropht.ClassWalletObject.ListRemoteNodeBanned[node] =
                            ClassUtils.DateUnixTimeNowSecond();
                        ClassPeerList.IncrementPeerDisconnect(node);
                    }
                }


                await Program.WalletXiropht.ClassWalletObject.DisconnectRemoteNodeTokenSync();

                Program.WalletXiropht.ClassWalletObject.WalletOnUseSync = false;
            }

            Program.WalletXiropht.ClassWalletObject.InReceiveTransaction = false;
        }