Пример #1
0
        private List <string> AttachToTangleStatement(
            Hash trunkTransaction, Hash branchTransaction,
            int minWeightMagnitude, List <string> trytes)
        {
            lock (_syncRoot)
            {
                List <TransactionViewModel> transactionViewModels = new List <TransactionViewModel>();

                Hash prevTransaction = null;
                _pearlDiver = new PearlDiver();

                int[] transactionTrits = Converter.AllocateTritsForTrytes(TrytesSize);

                foreach (string tryte in trytes)
                {
                    var  startTime = DateTime.Now;
                    long timestamp = TimeStamp.Now();
                    try
                    {
                        Converter.Trits(tryte, transactionTrits, 0);
                        //branch and trunk
                        Array.Copy((prevTransaction ?? trunkTransaction).Trits(), 0,
                                   transactionTrits, TransactionViewModel.TrunkTransactionTrinaryOffset,
                                   TransactionViewModel.TrunkTransactionTrinarySize);
                        Array.Copy((prevTransaction == null ? branchTransaction : trunkTransaction).Trits(), 0,
                                   transactionTrits, TransactionViewModel.BranchTransactionTrinaryOffset,
                                   TransactionViewModel.BranchTransactionTrinarySize);

                        //attachment fields: tag and timestamps
                        //tag - copy the obsolete tag to the attachment tag field only if tag isn't set.
                        var tagTrits = ArrayUtils.SubArray(transactionTrits,
                                                           TransactionViewModel.TagTrinaryOffset,
                                                           TransactionViewModel.TagTrinarySize);
                        if (Array.TrueForAll(tagTrits, s => s == 0))
                        {
                            Array.Copy(transactionTrits, TransactionViewModel.ObsoleteTagTrinaryOffset,
                                       transactionTrits, TransactionViewModel.TagTrinaryOffset,
                                       TransactionViewModel.TagTrinarySize);
                        }

                        Converter.CopyTrits(timestamp, transactionTrits,
                                            TransactionViewModel.AttachmentTimestampTrinaryOffset,
                                            TransactionViewModel.AttachmentTimestampTrinarySize);
                        Converter.CopyTrits(0, transactionTrits,
                                            TransactionViewModel.AttachmentTimestampLowerBoundTrinaryOffset,
                                            TransactionViewModel.AttachmentTimestampLowerBoundTrinarySize);
                        Converter.CopyTrits(MaxTimestampValue, transactionTrits,
                                            TransactionViewModel.AttachmentTimestampUpperBoundTrinaryOffset,
                                            TransactionViewModel.AttachmentTimestampUpperBoundTrinarySize);

                        if (!_pearlDiver.Search(transactionTrits, minWeightMagnitude, 0))
                        {
                            transactionViewModels.Clear();
                            break;
                        }

                        //validate PoW - throws exception if invalid
                        TransactionViewModel transactionViewModel =
                            TransactionValidator.Validate(transactionTrits,
                                                          _instance.TransactionValidator.MinWeightMagnitude);

                        transactionViewModels.Add(transactionViewModel);
                        prevTransaction = transactionViewModel.Hash;
                    }
                    finally
                    {
                        IncreaseEllapsedTimePoW(DateTime.Now - startTime);
                        IncreaseCounterPoW();
                        if ((GetCounterPoW() % 100) == 0)
                        {
                            string sb = $"Last 100 PoW consumed {GetEllapsedTimePoW().TotalSeconds:F3} seconds processing time.";

                            Log.Info(sb);
                            ResetCounterPow();
                            ResetEllapsedTimePoW();
                        }
                    }
                }

                List <string> elements = new List <string>();
                for (int i = transactionViewModels.Count; i-- > 0;)
                {
                    elements.Add(Converter.Trytes(transactionViewModels[i].Trits()));
                }

                return(elements);
            }
        }