예제 #1
0
파일: RutaDAO.cs 프로젝트: jesumarquez/lt
 public void UndeleteRoutes(GrupoRuta grupo)
 {
     using (SmartTransaction transaction = SmartTransaction.BeginTransaction())
     {
         try
         {
             UndeleteRoutesWithoutTransaction(grupo);
             try
             {
                 transaction.Commit();
             }
             catch (Exception ex)
             {
                 STrace.Exception(typeof(RutaDAO).FullName, ex, "Exception in UndeleteRoutes(GrupoRuta) -> transaction.Commit();");
                 throw ex;
             }
         }
         catch (Exception ex)
         {
             STrace.Exception(typeof(RutaDAO).FullName, ex, "Exception in UndeleteRoutes(GrupoRuta)");
             try
             {
                 transaction.Rollback();
             }
             catch (Exception ex2)
             {
                 STrace.Exception(typeof(RutaDAO).FullName, ex2, "Exception in UndeleteRoutes(GrupoRuta) -> transaction.Rollback();");
             }
             throw ex;
         }
     }
 }
예제 #2
0
        public async Task ConfirmTransactionTestAsync()
        {
            var transactionProcessor = await CreateTransactionProcessorAsync();

            var keys          = transactionProcessor.KeyManager.GetKeys().ToArray();
            int coinsReceived = 0;
            int confirmed     = 0;

            transactionProcessor.CoinReceived     += (s, e) => coinsReceived++;
            transactionProcessor.CoinSpent        += (s, e) => throw new InvalidOperationException("We are not spending the coin.");
            transactionProcessor.SpenderConfirmed += (s, e) => confirmed++;

            // A confirmed segwit transaction for us
            var tx = CreateCreditingTransaction(keys[0].PubKey.WitHash.ScriptPubKey, Money.Coins(1.0m));

            transactionProcessor.Process(tx);
            Assert.Equal(1, coinsReceived);

            var coin = Assert.Single(transactionProcessor.Coins);

            Assert.False(coin.Confirmed);

            var tx2 = new SmartTransaction(tx.Transaction.Clone(), new Height(54321));

            Assert.Equal(tx.GetHash(), tx2.GetHash());
            transactionProcessor.Process(tx2);
            Assert.Equal(1, coinsReceived);
            Assert.True(coin.Confirmed);

            Assert.Equal(0, confirmed);
        }
        private async Task BroadcastTransactionWithRpcAsync(SmartTransaction transaction)
        {
            await RpcClient.SendRawTransactionAsync(transaction.Transaction).ConfigureAwait(false);

            BelieveTransaction(transaction);
            Logger.LogInfo($"Transaction is successfully broadcasted with RPC: {transaction.GetHash()}.");
        }
예제 #4
0
        private void AnalyzeCoinjoin(SmartTransaction tx, int newInputAnonset, ISet <HdPubKey> distinctWalletInputPubKeys)
        {
            var indistinguishableWalletOutputs = tx
                                                 .WalletOutputs.GroupBy(x => x.Amount)
                                                 .ToDictionary(x => x.Key, y => y.Count());

            var anonsets = tx.Transaction.GetAnonymitySets(tx.WalletOutputs.Select(x => x.Index));

            foreach (var newCoin in tx.WalletOutputs.ToArray())
            {
                // Begin estimating the anonymity set size based on the number of
                // equivalent outputs that the i-th output has in in the transaction.
                int anonset = anonsets[newCoin.Index];

                // Picking randomly an output would make our anonset: total/ours.
                anonset /= indistinguishableWalletOutputs[newCoin.Amount];

                // Account for the inherited anonymity set size from the inputs in the
                // anonymity set size estimate.
                // The anonymity set size estimated for the input cluster is corrected
                // by -1 to avoid double counting ourselves in the anonset.
                // Stated differently, the right value to use for the calculation is not the
                // anonymity set size, but the subset of only the other participants, since
                // every output must belong to a member of the set.
                anonset += newInputAnonset - 1;

                HdPubKey hdPubKey = newCoin.HdPubKey;
                uint256  txid     = tx.GetHash();
                if (hdPubKey.AnonymitySet == HdPubKey.DefaultHighAnonymitySet)
                {
                    // If the new coin's HD pubkey haven't been used yet
                    // then its anonset haven't been set yet.
                    // In that case the acquired anonset does not have to be intersected with the default anonset,
                    // so this coin gets the aquired anonset.
                    hdPubKey.SetAnonymitySet(anonset, txid);
                }
                else if (distinctWalletInputPubKeys.Contains(hdPubKey))
                {
                    // If it's a reuse of an input's pubkey, then intersection punishment is senseless.
                    hdPubKey.SetAnonymitySet(newInputAnonset, txid);
                }
                else if (tx.WalletOutputs.Where(x => x != newCoin).Select(x => x.HdPubKey).Contains(hdPubKey))
                {
                    // If it's a reuse of another output' pubkey, then intersection punishment can only go as low as the inherited anonset.
                    hdPubKey.SetAnonymitySet(Math.Max(newInputAnonset, Intersect(new[] { anonset, hdPubKey.AnonymitySet }, 1)), txid);
                }
                else if (hdPubKey.AnonymitySetReasons.Contains(txid))
                {
                    // If we already processed this transaction for this script
                    // then we'll go with normal processing, it's not an address reuse,
                    // it's just we're processing the transaction twice.
                    hdPubKey.SetAnonymitySet(anonset, txid);
                }
                else
                {
                    // It's address reuse.
                    hdPubKey.SetAnonymitySet(Intersect(new[] { anonset, hdPubKey.AnonymitySet }, 1), txid);
                }
            }
        }
예제 #5
0
        /// <summary>
        /// Sets clusters and anonymity sets for related HD public keys.
        /// </summary>
        public void Analyze(SmartTransaction tx)
        {
            var inputCount  = tx.Transaction.Inputs.Count;
            var outputCount = tx.Transaction.Outputs.Count;

            var ownInputCount  = tx.WalletInputs.Count;
            var ownOutputCount = tx.WalletOutputs.Count;

            if (ownInputCount == 0)
            {
                AnalyzeReceive(tx);
            }
            else if (inputCount == ownInputCount && outputCount != ownOutputCount)
            {
                AnalyzeNormalSpend(tx);
            }
            else
            {
                AnalyzeWalletInputs(tx, out HashSet <HdPubKey> distinctWalletInputPubKeys, out int newInputAnonset);

                if (inputCount == ownInputCount)
                {
                    AnalyzeSelfSpend(tx, newInputAnonset);
                }
                else
                {
                    AnalyzeCoinjoin(tx, newInputAnonset, distinctWalletInputPubKeys);
                }

                AdjustWalletInputs(tx, distinctWalletInputPubKeys, newInputAnonset);
            }

            AnalyzeClusters(tx);
        }
예제 #6
0
        public BroadcastTransactionViewModel(
            BitcoinStore store,
            Network network,
            TransactionBroadcaster broadcaster,
            SmartTransaction transaction)
        {
            Title = "Broadcast Transaction";

            var nullMoney  = new Money(-1L);
            var nullOutput = new TxOut(nullMoney, Script.Empty);

            var psbt = PSBT.FromTransaction(transaction.Transaction, network);

            TxOut GetOutput(OutPoint outpoint) =>
            store.TransactionStore.TryGetTransaction(outpoint.Hash, out var prevTxn)
                                        ? prevTxn.Transaction.Outputs[outpoint.N]
                                        : nullOutput;

            var inputAddressAmount = psbt.Inputs
                                     .Select(x => x.PrevOut)
                                     .Select(GetOutput)
                                     .ToArray();

            var outputAddressAmount = psbt.Outputs
                                      .Select(x => x.GetCoin().TxOut)
                                      .ToArray();

            var psbtTxn = psbt.GetOriginalTransaction();

            _transactionId     = psbtTxn.GetHash().ToString();
            _inputCount        = inputAddressAmount.Length;
            _inputCountString  = $" input{TextHelpers.AddSIfPlural(_inputCount)} and ";
            _outputCount       = outputAddressAmount.Length;
            _outputCountString = $" output{TextHelpers.AddSIfPlural(_outputCount)}.";
            _totalInputValue   = inputAddressAmount.Any(x => x.Value == nullMoney)
                                ? null
                                : inputAddressAmount.Select(x => x.Value).Sum();
            _totalOutputValue = outputAddressAmount.Any(x => x.Value == nullMoney)
                                ? null
                                : outputAddressAmount.Select(x => x.Value).Sum();
            _networkFee = TotalInputValue is null || TotalOutputValue is null
                                ? null
                                : TotalInputValue - TotalOutputValue;

            EnableCancel = true;

            EnableBack = false;

            this.WhenAnyValue(x => x.IsBusy)
            .Subscribe(x => EnableCancel = !x);

            var nextCommandCanExecute = this.WhenAnyValue(x => x.IsBusy)
                                        .Select(x => !x);

            NextCommand = ReactiveCommand.CreateFromTask(
                async() => await OnNext(broadcaster, transaction),
                nextCommandCanExecute);

            EnableAutoBusyOn(NextCommand);
        }
예제 #7
0
        /// <returns>transactions it processed, empty if not processed any</returns>
        private HashSet <SmartTransaction> ProcessTransactions(IEnumerable <Transaction> transactions, Height height)
        {
            var processedTransactions = new HashSet <SmartTransaction>();

            try
            {
                // Process all transactions
                foreach (var tx in transactions)
                {
                    var smartTx = new SmartTransaction(tx, height);
                    if (ProcessTransaction(smartTx))
                    {
                        processedTransactions.Add(smartTx);
                    }
                }

                // If processed any then do it again recursively until zero new is processed
                if (processedTransactions.Count > 0)
                {
                    var newlyProcessedTransactions = ProcessTransactions(transactions, height);
                    foreach (var ptx in newlyProcessedTransactions)
                    {
                        processedTransactions.Add(ptx);
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"Ignoring {nameof(ProcessBlock)} exception at height {height}:");
                Debug.WriteLine(ex);
            }

            return(processedTransactions);
        }
        private async Task BroadcastTransactionToBackendAsync(SmartTransaction transaction)
        {
            Logger.LogInfo("Broadcasting with backend...");
            using (var client = new WasabiClient(Synchronizer.WasabiClient.TorClient.DestinationUriAction, Synchronizer.WasabiClient.TorClient.TorSocks5EndPoint))
            {
                try
                {
                    await client.BroadcastAsync(transaction).ConfigureAwait(false);
                }
                catch (HttpRequestException ex2) when(ex2.Message.Contains("bad-txns-inputs-missingorspent", StringComparison.InvariantCultureIgnoreCase) ||
                                                      ex2.Message.Contains("missing-inputs", StringComparison.InvariantCultureIgnoreCase) ||
                                                      ex2.Message.Contains("txn-mempool-conflict", StringComparison.InvariantCultureIgnoreCase))
                {
                    if (transaction.Transaction.Inputs.Count == 1)                     // If we tried to only spend one coin, then we can mark it as spent. If there were more coins, then we do not know.
                    {
                        OutPoint input = transaction.Transaction.Inputs.First().PrevOut;
                        lock (WalletServicesLock)
                        {
                            foreach (var walletService in AliveWalletServices)
                            {
                                SmartCoin coin = walletService.Coins.GetByOutPoint(input);
                                if (coin != default)
                                {
                                    coin.SpentAccordingToBackend = true;
                                }
                            }
                        }
                    }
                }
            }

            BelieveTransaction(transaction);

            Logger.LogInfo($"Transaction is successfully broadcasted to backend: {transaction.GetHash()}.");
        }
예제 #9
0
        public void SmartCoinEquality()
        {
            var tx    = Transaction.Parse("0100000000010176f521a178a4b394b647169a89b29bb0d95b6bce192fd686d533eb4ea98464a20000000000ffffffff02ed212d020000000016001442da650f25abde0fef57badd745df7346e3e7d46fbda6400000000001976a914bd2e4029ce7d6eca7d2c3779e8eac36c952afee488ac02483045022100ea43ccf95e1ac4e8b305c53761da7139dbf6ff164e137a6ce9c09e15f316c22902203957818bc505bbafc181052943d7ab1f3ae82c094bf749813e8f59108c6c268a012102e59e61f20c7789aa73faf5a92dc8c0424e538c635c55d64326d95059f0f8284200000000", Network.TestNet);
            var index = 0U;
            var km    = KeyManager.CreateNew(out _, "", Network.Main);
            var hdpk1 = km.GenerateNewKey(SmartLabel.Empty, KeyState.Clean, false);
            var hdpk2 = km.GenerateNewKey(SmartLabel.Empty, KeyState.Clean, false);

            tx.Outputs[0].ScriptPubKey = hdpk1.P2wpkhScript;
            tx.Outputs[1].ScriptPubKey = hdpk2.P2wpkhScript;

            var height = Height.Mempool;
            var stx    = new SmartTransaction(tx, height);

            var coin = new SmartCoin(stx, index, hdpk1);

            // If the txId or the index differ, equality should think it's a different coin.
            var differentCoin = new SmartCoin(stx, index + 1, hdpk2);

            // If the txId and the index are the same, equality should think it's the same coin.
            var sameCoin = new SmartCoin(stx, index, hdpk1);

            Assert.Equal(coin, sameCoin);
            Assert.NotEqual(coin, differentCoin);
        }
예제 #10
0
        private void ProcesarViaje(int idViaje, bool regenera)
        {
            using (var transaction = SmartTransaction.BeginTransaction(IsolationLevel.ReadUncommitted))
            {
                try
                {
                    var viaje = DaoFactory.ViajeDistribucionDAO.FindById(idViaje);

                    if (!regenera && HasBeenProcessed(idViaje))
                    {
                        STrace.Trace(GetType().FullName, string.Format("Viaje ya procesado: {0}", idViaje));
                    }
                    else
                    {
                        DaoFactory.DatamartViajeDAO.DeleteRecords(idViaje);
                        ProcessViaje(viaje);
                        STrace.Trace(GetType().FullName, string.Format("Viaje procesado: {0}", idViaje));
                    }
                    transaction.Commit();
                }
                catch (Exception ex)
                {
                    transaction.Rollback();
                    throw ex;
                }
                finally
                {
                    ClearData();
                }
            }
        }
예제 #11
0
        protected void BtnGuardar_OnClick(object sender, EventArgs e)
        {
            ValidarDatosVigencia();

            using (var transaction = SmartTransaction.BeginTransaction())
            {
                if (EditObject.Id == 0)
                {
                    GuardarNuevaLinea();
                }

                var nuevaVigencia = new VigenciaPlanLinea
                {
                    Inicio          = SecurityExtensions.ToDataBaseDateTime(dtDesde.SelectedDate.Value),
                    LineaTelefonica = EditObject,
                    Plan            = cbPlan.Selected > 0 ? DAOFactory.PlanDAO.FindById(cbPlan.Selected) : null
                };

                ValidarCondicionesVigencia(nuevaVigencia);

                EditObject.Vigencias.Add(nuevaVigencia);

                DAOFactory.LineaTelefonicaDAO.SaveOrUpdate(EditObject);

                transaction.Commit();
            }
            Response.Redirect(RedirectUrl);
        }
예제 #12
0
 private void DoDeleteAudit(TDaotype obj, Usuario user)
 {
     using (var transaction = SmartTransaction.BeginTransaction())
     {
         try
         {
             DoDeleteAuditWithoutTransaction(obj, user);
             try
             {
                 transaction.Commit();
             }
             catch (Exception ex)
             {
                 STrace.Exception(typeof(GenericDAO <TDaotype>).FullName, ex, "Exception in Update(TDaotype) -> transaction.Commit();");
                 throw ex;
             }
         }
         catch (Exception ex)
         {
             STrace.Exception(typeof(GenericDAO <TDaotype>).FullName, ex, "Exception in Update(TDaotype)");
             try
             {
                 transaction.Rollback();
             }
             catch (Exception ex2)
             {
                 STrace.Exception(typeof(GenericDAO <TDaotype>).FullName, ex2, "Exception in Update(TDaotype) -> transaction.Rollback();");
             }
             throw ex;
         }
     }
 }
예제 #13
0
 /// <summary>
 /// Updates the specified object whitin a transaction.
 /// </summary>
 /// <param name="obj"></param>
 public virtual void Update(TDaotype obj)
 {
     using (var transaction = SmartTransaction.BeginTransaction())
     {
         try
         {
             UpdateWithoutTransaction(obj);
             try
             {
                 transaction.Commit();
             }
             catch (Exception ex)
             {
                 STrace.Exception(typeof(GenericDAO <TDaotype>).FullName, ex, "Exception in Update(TDaotype) -> transaction.Commit();");
                 throw ex;
             }
         }
         catch (Exception ex)
         {
             STrace.Exception(typeof(GenericDAO <TDaotype>).FullName, ex, "Exception in Update(TDaotype)");
             try
             {
                 transaction.Rollback();
             }
             catch (Exception ex2)
             {
                 STrace.Exception(typeof(GenericDAO <TDaotype>).FullName, ex2, "Exception in Update(TDaotype) -> transaction.Rollback();");
             }
             throw ex;
         }
     }
 }
예제 #14
0
        public async Task SendTransactionAsync(SmartTransaction transaction)
        {
            try
            {
                // Broadcast to a random node.
                // Wait until it arrives to at least two other nodes.
                // If something's wrong, fall back broadcasting with rpc, then backend.

                if (Network == Network.RegTest)
                {
                    throw new InvalidOperationException($"Transaction broadcasting to nodes does not work in {Network.RegTest}.");
                }

                Node node = Nodes.ConnectedNodes.RandomElement();
                while (node is null || !node.IsConnected || Nodes.ConnectedNodes.Count < 5)
                {
                    // As long as we are connected to at least 4 nodes, we can always try again.
                    // 3 should be enough, but make it 5 so 2 nodes could disconnect in the meantime.
                    if (Nodes.ConnectedNodes.Count < 5)
                    {
                        throw new InvalidOperationException("We are not connected to enough nodes.");
                    }
                    await Task.Delay(100).ConfigureAwait(false);

                    node = Nodes.ConnectedNodes.RandomElement();
                }
                await BroadcastTransactionToNetworkNodeAsync(transaction, node).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                Logger.LogInfo($"Random node could not broadcast transaction. Reason: {ex.Message}.");
                Logger.LogDebug(ex);

                if (RpcClient is { })
예제 #15
0
        public void SmartTransactionSerialization()
        {
            var tx     = Transaction.Parse("02000000040aa8d0af84518df6e3a60c5bb19d9c3fcc3dc6e26b2f2449e8d7bf8d3fe84b87010000006a473044022018dfe9216c1209dd6c2b6c1607dbac4e499c1fce4878bc7d5d83fccbf3e24c9402202cac351c9c6a2b5eef338cbf0ec000d8de1c05e96a904cbba2b9e6ffc2d4e19501210364cc39da1091b1a9c12ec905a14a9e8478f951f7a1accdabeb40180533f2eaa5feffffff112c07d0f5e0617d720534f0b2b84dc0d5b7314b358c3ab338823b9e5bfbddf5010000006b483045022100ec155e7141e74661ee511ae980150a6c89261f31070999858738369afc28f2b6022006230d2aa24fac110b74ef15b84371486cf76c539b335a253c14462447912a300121020c2f41390f031d471b22abdb856e6cdbe0f4d74e72c197469bfd54e5a08f7e67feffffff38e799b8f6cf04fd021a9b135cdcd347da7aac4fd8bb8d0da9316a9fb228bb6e000000006b483045022100fc1944544a3f96edd8c8a9795c691e2725612b5ab2e1c999be11a2a4e3f841f1022077b2e088877829edeada0c707a9bb577aa79f26dafacba3d1d2d047f52524296012102e6015963dff9826836400cf8f45597c0705757d5dcdc6bf734f661c7dab89e69feffffff64c3f0377e86625123f2f1ee229319ed238e8ca8b7dda5bc080a2c5ecb984629000000006a47304402204233a90d6296182914424fd2901e16e6f5b13b451b67b0eec25a5eaacc5033c902203d8a13ef0b494c12009663475458e51da6bd55cc67688264230ece81d3eeca24012102f806d7152da2b52c1d9ad928e4a6253ccba080a5b9ab9efdd80e37274ac67f9bfeffffff0290406900000000001976a91491ac4e49b66f845180d98d8f8be6121588be6e3b88ac52371600000000001976a9142f44ed6749e8c84fd476e4440741f7e6f55542fa88acadd30700", Network.TestNet);
            var tx2    = Transaction.Parse("02000000040aa8d0af84518df6e3a60c5bb19d9c3fcc3dc6e26b2f2449e8d7bf8d3fe84b87010000006a473044022018dfe9216c1209dd6c2b6c1607dbac4e499c1fce4878bc7d5d83fccbf3e24c9402202cac351c9c6a2b5eef338cbf0ec000d8de1c05e96a904cbba2b9e6ffc2d4e19501210364cc39da1091b1a9c12ec905a14a9e8478f951f7a1accdabeb40180533f2eaa5feffffff112c07d0f5e0617d720534f0b2b84dc0d5b7314b358c3ab338823b9e5bfbddf5010000006b483045022100ec155e7141e74661ee511ae980150a6c89261f31070999858738369afc28f2b6022006230d2aa24fac110b74ef15b84371486cf76c539b335a253c14462447912a300121020c2f41390f031d471b22abdb856e6cdbe0f4d74e72c197469bfd54e5a08f7e67feffffff38e799b8f6cf04fd021a9b135cdcd347da7aac4fd8bb8d0da9316a9fb228bb6e000000006b483045022100fc1944544a3f96edd8c8a9795c691e2725612b5ab2e1c999be11a2a4e3f841f1022077b2e088877829edeada0c707a9bb577aa79f26dafacba3d1d2d047f52524296012102e6015963dff9826836400cf8f45597c0705757d5dcdc6bf734f661c7dab89e69feffffff64c3f0377e86625123f2f1ee229319ed238e8ca8b7dda5bc080a2c5ecb984629000000006a47304402204233a90d6296182914424fd2901e16e6f5b13b451b67b0eec25a5eaacc5033c902203d8a13ef0b494c12009663475458e51da6bd55cc67688264230ece81d3eeca24012102f806d7152da2b52c1d9ad928e4a6253ccba080a5b9ab9efdd80e37274ac67f9bfeffffff0290406900000000001976a91491ac4e49b66f845180d98d8f8be6121588be6e3b88ac52371600000000001976a9142f44ed6749e8c84fd476e4440741f7e6f55542fa88acadd30700", Network.Main);
            var tx3    = Transaction.Parse("02000000040aa8d0af84518df6e3a60c5bb19d9c3fcc3dc6e26b2f2449e8d7bf8d3fe84b87010000006a473044022018dfe9216c1209dd6c2b6c1607dbac4e499c1fce4878bc7d5d83fccbf3e24c9402202cac351c9c6a2b5eef338cbf0ec000d8de1c05e96a904cbba2b9e6ffc2d4e19501210364cc39da1091b1a9c12ec905a14a9e8478f951f7a1accdabeb40180533f2eaa5feffffff112c07d0f5e0617d720534f0b2b84dc0d5b7314b358c3ab338823b9e5bfbddf5010000006b483045022100ec155e7141e74661ee511ae980150a6c89261f31070999858738369afc28f2b6022006230d2aa24fac110b74ef15b84371486cf76c539b335a253c14462447912a300121020c2f41390f031d471b22abdb856e6cdbe0f4d74e72c197469bfd54e5a08f7e67feffffff38e799b8f6cf04fd021a9b135cdcd347da7aac4fd8bb8d0da9316a9fb228bb6e000000006b483045022100fc1944544a3f96edd8c8a9795c691e2725612b5ab2e1c999be11a2a4e3f841f1022077b2e088877829edeada0c707a9bb577aa79f26dafacba3d1d2d047f52524296012102e6015963dff9826836400cf8f45597c0705757d5dcdc6bf734f661c7dab89e69feffffff64c3f0377e86625123f2f1ee229319ed238e8ca8b7dda5bc080a2c5ecb984629000000006a47304402204233a90d6296182914424fd2901e16e6f5b13b451b67b0eec25a5eaacc5033c902203d8a13ef0b494c12009663475458e51da6bd55cc67688264230ece81d3eeca24012102f806d7152da2b52c1d9ad928e4a6253ccba080a5b9ab9efdd80e37274ac67f9bfeffffff0290406900000000001976a91491ac4e49b66f845180d98d8f8be6121588be6e3b88ac52371600000000001976a9142f44ed6749e8c84fd476e4440741f7e6f55542fa88acadd30700", Network.RegTest);
            var height = Height.MemPool;

            var smartTx  = new SmartTransaction(tx, height);
            var smartTx2 = new SmartTransaction(tx2, height);
            var smartTx3 = new SmartTransaction(tx3, height);

            var serialized   = JsonConvert.SerializeObject(smartTx);
            var deserialized = JsonConvert.DeserializeObject <SmartTransaction>(serialized);

            var serialized2   = JsonConvert.SerializeObject(smartTx2);
            var deserialized2 = JsonConvert.DeserializeObject <SmartTransaction>(serialized2);

            var serialized3   = JsonConvert.SerializeObject(smartTx3);
            var deserialized3 = JsonConvert.DeserializeObject <SmartTransaction>(serialized3);

            Assert.Equal(smartTx, deserialized);
            Assert.Equal(smartTx.Height, deserialized.Height);
            Assert.Equal(deserialized, deserialized2);
            Assert.Equal(deserialized, deserialized3);
            Assert.True(smartTx.Transaction == deserialized3);
            Assert.True(smartTx.Equals(deserialized2.Transaction));
            object sto = deserialized;

            Assert.True(smartTx.Equals(sto));
            object to = deserialized.Transaction;

            Assert.True(smartTx.Equals(deserialized.Transaction));
            // ToDo: Assert.True(smartTx.Equals(to));
        }
예제 #16
0
        protected override void OnDelete()
        {
            using (var transaction = SmartTransaction.BeginTransaction())
            {
                EditObject.Estado = ConsumoCabecera.Estados.Eliminado;
                DAOFactory.ConsumoCabeceraDAO.SaveOrUpdate(EditObject);

                ////// ACTUALIZAR STOCK //////

                if (EditObject.Deposito != null ||
                    EditObject.DepositoDestino != null)
                {
                    var detalles = EditObject.Detalles.Cast <ConsumoDetalle>();
                    foreach (var consumoDetalle in detalles)
                    {
                        if (EditObject.Deposito != null)
                        {
                            var stock = DAOFactory.StockDAO.GetByDepositoAndInsumo(EditObject.Deposito.Id, consumoDetalle.Insumo.Id);
                            stock.Cantidad += consumoDetalle.Cantidad;
                            DAOFactory.StockDAO.SaveOrUpdate(stock);
                        }

                        if (EditObject.DepositoDestino != null)
                        {
                            var stock = DAOFactory.StockDAO.GetByDepositoAndInsumo(EditObject.DepositoDestino.Id, consumoDetalle.Insumo.Id);
                            stock.Cantidad -= consumoDetalle.Cantidad;
                            DAOFactory.StockDAO.SaveOrUpdate(stock);
                        }
                    }
                }
                //////////////////////////////

                transaction.Commit();
            }
        }
        public async Task UpdateTransactionHeightAfterConfirmationAsync()
        {
            var transactionProcessor = await CreateTransactionProcessorAsync();

            // An unconfirmed segwit transaction for us
            var key = transactionProcessor.KeyManager.GetKeys().First();

            var tx = CreateCreditingTransaction(key.PubKey.WitHash.ScriptPubKey, Money.Coins(1.0m));

            transactionProcessor.Process(tx);

            Assert.True(transactionProcessor.TransactionStore.ConfirmedStore.IsEmpty());
            var cachedTx = Assert.Single(transactionProcessor.TransactionStore.MempoolStore.GetTransactions());
            var coin     = Assert.Single(transactionProcessor.Coins);

            Assert.Equal(Height.Mempool, cachedTx.Height);
            Assert.Equal(Height.Mempool, coin.Height);

            // Now it is confirmed
            var blockHeight = new Height(77551);

            tx = new SmartTransaction(tx.Transaction, blockHeight);
            var relevant = transactionProcessor.Process(tx);

            Assert.True(relevant);
            Assert.Single(transactionProcessor.Coins);

            // Transaction store assertions
            Assert.True(transactionProcessor.TransactionStore.MempoolStore.IsEmpty());
            cachedTx = Assert.Single(transactionProcessor.TransactionStore.ConfirmedStore.GetTransactions());
            Assert.Equal(blockHeight, cachedTx.Height);
            coin = Assert.Single(transactionProcessor.Coins);
            Assert.Equal(blockHeight, coin.Height);
            Assert.True(coin.Confirmed);
        }
예제 #18
0
        public void UpdateTransactionHeightAfterConfirmation()
        {
            var transactionProcessor = CreateTransactionProcessor();

            // An unconfirmed segwit transaction for us
            var key = transactionProcessor.KeyManager.GetKeys().First();

            var tx = CreateCreditingTransaction(key.PubKey.WitHash.ScriptPubKey, Money.Coins(1.0m));

            transactionProcessor.TransactionHashes.Append(tx.GetHash());             // This transaction was already seen before
            transactionProcessor.Process(tx);

            var cachedTx = Assert.Single(transactionProcessor.TransactionCache);
            var coin     = Assert.Single(transactionProcessor.Coins);

            Assert.Equal(Height.Mempool, cachedTx.Height);
            Assert.Equal(Height.Mempool, coin.Height);

            // Now it is confirmed
            var blockHeight = new Height(77551);

            tx = new SmartTransaction(tx.Transaction, blockHeight);
            var relevant = transactionProcessor.Process(tx);

            Assert.True(relevant);
            Assert.Single(transactionProcessor.Coins);
            cachedTx = Assert.Single(transactionProcessor.TransactionCache);
            Assert.NotEqual(Height.Mempool, cachedTx.Height);
            coin = Assert.Single(transactionProcessor.Coins);
            Assert.Equal(blockHeight, coin.Height);

            Assert.Empty(transactionProcessor.TransactionHashes);
        }
예제 #19
0
        private async Task BroadcastTransactionToBackendAsync(SmartTransaction transaction)
        {
            Logger.LogInfo("Broadcasting with backend...");
            using (TorHttpClient torHttpClient = Synchronizer.WasabiClientFactory.NewBackendTorHttpClient(isolateStream: true))
            {
                var client = new WasabiClient(torHttpClient);

                try
                {
                    await client.BroadcastAsync(transaction).ConfigureAwait(false);
                }
                catch (HttpRequestException ex2) when(RpcErrorTools.IsSpentError(ex2.Message))
                {
                    if (transaction.Transaction.Inputs.Count == 1)                     // If we tried to only spend one coin, then we can mark it as spent. If there were more coins, then we do not know.
                    {
                        OutPoint input = transaction.Transaction.Inputs.First().PrevOut;
                        foreach (var coin in WalletManager.CoinsByOutPoint(input))
                        {
                            coin.SpentAccordingToBackend = true;
                        }
                    }

                    throw;
                }
            }

            BelieveTransaction(transaction);

            Logger.LogInfo($"Transaction is successfully broadcasted to backend: {transaction.GetHash()}.");
        }
예제 #20
0
        protected override void OnSave()
        {
            using (var transaction = SmartTransaction.BeginTransaction())
            {
                try
                {
                    EditObject.Cliente     = DAOFactory.ClienteDAO.FindById(ddlCliente.Selected);
                    EditObject.Responsable = cbResponsable.Selected > 0 ? DAOFactory.EmpleadoDAO.FindById(cbResponsable.Selected) : null;
                    EditObject.Codigo      = txtCodigo.Text;
                    EditObject.Descripcion = txtDescripcion.Text;
                    EditObject.Telefono    = txtTelefono.Text;
                    EditObject.Nomenclado  = true;

                    EditObject.Comentario1 = txtComentario1.Text;
                    EditObject.Comentario2 = txtComentario2.Text;
                    EditObject.Comentario3 = txtComentario3.Text;

                    if (chkExistente.Checked)
                    {
                        EditObject.ReferenciaGeografica = SelectGeoRef1.Selected > 0
                            ? DAOFactory.ReferenciaGeograficaDAO.FindById(SelectGeoRef1.Selected)
                            : null;
                    }
                    else
                    {
                        EditObject.ReferenciaGeografica             = EditEntityGeoRef1.GetNewGeoRefference();
                        EditObject.ReferenciaGeografica.Descripcion = EditObject.Descripcion;
                        EditObject.ReferenciaGeografica.Empresa     = cbEmpresa.Selected > 0 ? DAOFactory.EmpresaDAO.FindById(cbEmpresa.Selected) : null;
                        EditObject.ReferenciaGeografica.Linea       = cbLinea.Selected > 0 ? DAOFactory.LineaDAO.FindById(cbLinea.Selected) : null;

                        var code = EditObject.Codigo;
                        EditObject.ReferenciaGeografica.Codigo = code;

                        var i = 1;

                        var byCode = DAOFactory.ReferenciaGeograficaDAO.FindByCodigoStartWith(cbEmpresa.SelectedValues, cbLinea.SelectedValues,
                                                                                              new[] { EditEntityGeoRef1.TipoReferenciaGeograficaId }, code);

                        while (byCode.Any(r => r.Codigo == code && EditObject.ReferenciaGeografica.Id != r.Id))
                        {
                            code += "(" + i++ + ")";
                        }

                        EditObject.ReferenciaGeografica.Codigo = code;

                        DAOFactory.ReferenciaGeograficaDAO.SingleSaveOrUpdate(EditObject.ReferenciaGeografica);
                        STrace.Trace("QtreeReset", "PtoEntregaAlta");
                    }

                    DAOFactory.PuntoEntregaDAO.SaveOrUpdate(EditObject);
                    transaction.Commit();
                }
                catch (Exception ex)
                {
                    transaction.Rollback();
                    throw ex;
                }
            }
        }
예제 #21
0
        protected override async Task BuildTransaction(string password, PaymentIntent payments, FeeStrategy feeStrategy, bool allowUnconfirmed = false, IEnumerable <OutPoint> allowedInputs = null)
        {
            BuildTransactionResult result = await Task.Run(() => Wallet.BuildTransaction(Password, payments, feeStrategy, allowUnconfirmed: true, allowedInputs: allowedInputs, GetPayjoinClient()));

            MainWindowViewModel.Instance.StatusBar.TryAddStatus(StatusType.SigningTransaction);
            SmartTransaction signedTransaction = result.Transaction;

            if (Wallet.KeyManager.IsHardwareWallet && !result.Signed)             // If hardware but still has a privkey then it's password, then meh.
            {
                try
                {
                    IsHardwareBusy = true;
                    MainWindowViewModel.Instance.StatusBar.TryAddStatus(StatusType.AcquiringSignatureFromHardwareWallet);
                    var client = new HwiClient(Global.Network);

                    using var cts = new CancellationTokenSource(TimeSpan.FromMinutes(3));
                    PSBT signedPsbt = null;
                    try
                    {
                        try
                        {
                            signedPsbt = await client.SignTxAsync(Wallet.KeyManager.MasterFingerprint.Value, result.Psbt, cts.Token);
                        }
                        catch (PSBTException ex) when(ex.Message.Contains("NullFail"))
                        {
                            NotificationHelpers.Warning("Fall back to Unverified Inputs Mode, trying to sign again.");

                            // Ledger Nano S hackfix https://github.com/MetacoSA/NBitcoin/pull/888

                            var noinputtx = result.Psbt.Clone();

                            foreach (var input in noinputtx.Inputs)
                            {
                                input.NonWitnessUtxo = null;
                            }

                            signedPsbt = await client.SignTxAsync(Wallet.KeyManager.MasterFingerprint.Value, noinputtx, cts.Token);
                        }
                    }
                    catch (HwiException)
                    {
                        await PinPadViewModel.UnlockAsync();

                        signedPsbt = await client.SignTxAsync(Wallet.KeyManager.MasterFingerprint.Value, result.Psbt, cts.Token);
                    }
                    signedTransaction = signedPsbt.ExtractSmartTransaction(result.Transaction);
                }
                finally
                {
                    MainWindowViewModel.Instance.StatusBar.TryRemoveStatus(StatusType.AcquiringSignatureFromHardwareWallet);
                    IsHardwareBusy = false;
                }
            }

            MainWindowViewModel.Instance.StatusBar.TryAddStatus(StatusType.BroadcastingTransaction);
            await Task.Run(async() => await Global.TransactionBroadcaster.SendTransactionAsync(signedTransaction));

            ResetUi();
        }
 private static void AnalyzeReceive(SmartTransaction tx)
 {
     // No matter how much anonymity a user would had gained in a tx, if the money comes from outside, then make anonset 1.
     foreach (var key in tx.WalletOutputs.Select(x => x.HdPubKey))
     {
         key.SetAnonymitySet(1, tx.GetHash());
     }
 }
예제 #23
0
 public BuildTransactionResult(SmartTransaction transaction, PSBT psbt, bool signed, Money fee, decimal feePercentOfSent)
 {
     Transaction      = Guard.NotNull(nameof(transaction), transaction);
     Psbt             = Guard.NotNull(nameof(psbt), psbt);
     Signed           = signed;
     Fee              = fee ?? Money.Zero;
     FeePercentOfSent = feePercentOfSent;
 }
 public BuildTransactionResult(SmartTransaction transaction, PSBT psbt, bool signed, Money fee, decimal feePercentOfSent)
 {
     Transaction      = transaction;
     Psbt             = psbt;
     Signed           = signed;
     Fee              = fee;
     FeePercentOfSent = feePercentOfSent;
 }
예제 #25
0
        private static QtreeNode GetQtree(int empresa, int linea)
        {
            var lastMod = ReferenciaGeograficaDAO.GetLastUpdate(empresa, linea);
            var key     = GetQtreeKey(empresa, linea);

            var root = Qtrees.ContainsKey(key) ? Qtrees[key] : null;

            if (root != null && lastMod < root.LastUpdate)
            {
                return(root);
            }

            if (Monitor.TryEnter(Qtrees))
            {
                try
                {
                    STrace.Error("ResetQtree", string.Format("qtree UPDATE ---> Empresa: {0} - Linea: {1}", empresa, linea));

                    using (var transaction = SmartTransaction.BeginTransaction())
                    {
                        var daoFactory = new DAOFactory();
                        var geocercas  = daoFactory.ReferenciaGeograficaDAO.GetGeocercasFor(empresa, linea);
                        transaction.Commit();

                        var keyToRemove = string.Empty;
                        if (root != null)
                        {
                            keyToRemove = key;
                        }
                        root = new QtreeNode();

                        foreach (var geocerca in geocercas)
                        {
                            root.AddValue(geocerca);
                        }

                        if (keyToRemove != string.Empty)
                        {
                            Qtrees.Remove(keyToRemove);
                        }
                        Qtrees.Add(key, root);
                    }

                    STrace.Trace("DispatcherLock", string.Format("qtree NEW ---> {0} | {1}", empresa, linea));
                }
                finally
                {
                    Monitor.Exit(Qtrees);
                }
            }
            else
            {
                STrace.Trace("DispatcherLock", string.Format("qtree OLD ---> {0} | {1}", empresa, linea));
            }

            return(root);
        }
        private void BelieveTransaction(SmartTransaction transaction)
        {
            if (transaction.Height == Height.Unknown)
            {
                transaction.SetUnconfirmed();
            }

            WalletManager.Process(transaction);
        }
예제 #27
0
        /// <summary>
        /// Saves current object.
        /// </summary>
        protected override void OnSave()
        {
            var oldIcon     = EditObject.Icono;
            var newIcon     = SelectIcon2.Selected > 0 ? DAOFactory.IconoDAO.FindById(SelectIcon2.Selected) : null;
            var iconChanged = oldIcon != newIcon;

            EditObject.Codigo      = txtCodigo.Text.Trim();
            EditObject.Descripcion = txtDescripcion.Text.Trim();
            EditObject.Icono       = newIcon;

            EditObject.ControlaEntradaSalida = chkControlaES.Checked;
            EditObject.ControlaVelocidad     = chkControlaVelocidad.Checked;
            EditObject.InhibeAlarma          = chkInhibeAlarma.Checked;
            EditObject.EsZonaDeRiesgo        = chkZonaRiesgo.Checked;
            EditObject.ExcluirMonitor        = chkExcluyeMonitor.Checked;
            EditObject.EsTaller        = chkEsTaller.Checked;
            EditObject.EsControlAcceso = chkEsControlAcceso.Checked;

            EditObject.ControlaPermanencia        = chkControlaPermanencia.Checked;
            EditObject.ControlaPermanenciaEntrega = chkControlaPermanenciaEntrega.Checked;
            EditObject.MaximaPermanencia          = chkControlaPermanencia.Checked ? Convert.ToInt32((string)txtMaximaPermanencia.Text) : 0;
            EditObject.MaximaPermanenciaEntrega   = chkControlaPermanenciaEntrega.Checked ? Convert.ToInt32((string)txtMaximaPermanenciaEntrega.Text) : 0;

            EditObject.EsInicio     = chkInicio.Checked;
            EditObject.EsIntermedio = chkIntermedio.Checked;
            EditObject.EsFin        = chkFin.Checked;

            EditObject.Color.HexValue = ColorPicker.Color;

            EditObject.Linea   = cbLinea.Selected > 0 ? DAOFactory.LineaDAO.FindById(cbLinea.Selected) : null;
            EditObject.Empresa = EditObject.Linea != null
                                     ? EditObject.Linea.Empresa
                                     : cbEmpresa.Selected > 0 ? DAOFactory.EmpresaDAO.FindById(cbEmpresa.Selected) : null;

            if (EditObject.ControlaVelocidad)
            {
                AddSpeedLimits();
            }

            using (var transaction = SmartTransaction.BeginTransaction())
            {
                try
                {
                    DAOFactory.TipoReferenciaGeograficaDAO.SaveOrUpdate(EditObject);
                    if (EditMode && iconChanged)
                    {
                        UpdateGeoRefIcons(oldIcon, newIcon);
                    }
                    transaction.Commit();
                }
                catch (Exception ex)
                {
                    transaction.Rollback();
                    throw ex;
                }
            }
        }
예제 #28
0
        public async Task SendTransactionAsync(SmartTransaction transaction)
        {
            try
            {
                // Broadcast to a random node.
                // Wait until it arrives to at least two other nodes.
                // If something's wrong, fall back broadcasting with rpc, then backend.

                if (Network == Network.RegTest)
                {
                    throw new InvalidOperationException($"Transaction broadcasting to nodes does not work in {Network.RegTest}.");
                }

                Node node = Nodes.ConnectedNodes.RandomElement();
                while (node == default(Node) || !node.IsConnected || Nodes.ConnectedNodes.Count < 5)
                {
                    // As long as we are connected to at least 4 nodes, we can always try again.
                    // 3 should be enough, but make it 5 so 2 nodes could disconnect the meantime.
                    if (Nodes.ConnectedNodes.Count < 5)
                    {
                        throw new InvalidOperationException("We are not connected to enough nodes.");
                    }
                    await Task.Delay(100).ConfigureAwait(false);

                    node = Nodes.ConnectedNodes.RandomElement();
                }
                await BroadcastTransactionToNetworkNodeAsync(transaction, node).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                Logger.LogInfo($"Random node could not broadcast transaction. Reason: {ex.Message}.");
                Logger.LogDebug(ex);

                if (RpcClient != null)
                {
                    try
                    {
                        await BroadcastTransactionWithRpcAsync(transaction).ConfigureAwait(false);
                    }
                    catch (Exception ex2)
                    {
                        Logger.LogInfo($"RPC could not broadcast transaction. Reason: {ex2.Message}.");
                        Logger.LogDebug(ex2);

                        await BroadcastTransactionToBackendAsync(transaction).ConfigureAwait(false);
                    }
                }
                else
                {
                    await BroadcastTransactionToBackendAsync(transaction).ConfigureAwait(false);
                }
            }
            finally
            {
                BitcoinStore.MempoolService.TryRemoveFromBroadcastStore(transaction.GetHash(), out _);                 // Remove it just to be sure. Probably has been removed previously.
            }
        }
예제 #29
0
        public static SmartTransaction RandomSmartTransaction()
        {
            var tx = Transaction.Create(Network.Main);

            tx.Outputs.Add(Money.Coins(1), new Key());
            var stx = new SmartTransaction(tx, Height.Mempool);

            return(stx);
        }
예제 #30
0
        public SendSuccessViewModel(Wallet wallet, SmartTransaction finalTransaction)
        {
            _wallet           = wallet;
            _finalTransaction = finalTransaction;

            NextCommand = ReactiveCommand.Create(OnNext);

            SetupCancel(enableCancel: false, enableCancelOnEscape: true, enableCancelOnPressed: true);
        }