コード例 #1
0
        // ToDo: The finding of transaction in DB will probably has a better algorithm
        // The following one by one version is the preliminary design
        private async Task <Transaction> FindThePunishment(BalanceOperation op, MultisigOutputEntity output)
        {
            using (OffchainMonitorContext context = new OffchainMonitorContext())
            {
                var commitments = from c in context.Commitments
                                  where c.CommitmentOutput.TransactionId == output.TransactionId &&
                                  c.CommitmentOutput.OutputNumber == output.OutputNumber
                                  select c;

                if (commitments != null && commitments.Count() > 0)
                {
                    foreach (var c in commitments)
                    {
                        if (TransactionsMatch(c, op))
                        {
                            return(new Transaction(c.Punishment));
                        }
                    }
                }
                else
                {
                    // No commitment cosuming the specified output
                    return(null);
                }

                // No commitment found matching the specified transaction, spending multisig output
                return(null);
            }
        }
コード例 #2
0
        public async Task CheckCommitmentBroadcastOld()
        {
            string  multisig = null;
            Network network  = Network.TestNet;

            try
            {
                multisig = await settingsRepository.Get <string>("multisig");

                network = await Helper.GetNetwork(settingsRepository);
            }
            catch (Exception exp)
            {
                return;
            }

            var outputs = await qBitNinjaApiCaller.GetAddressBalance(multisig, true, true);

            MultisigOutputEntity desiredOutput = null;

            using (OffchainMonitorContext context = new OffchainMonitorContext())
            {
                desiredOutput = (from o in context.MultisigOutputs
                                 orderby o.LastSeen ascending
                                 select o).FirstOrDefault();
            }

            if (desiredOutput == null)
            {
                // There is no commitment
                return;
            }
            else
            {
                foreach (var op in outputs.Operations)
                {
                    var found = op.ReceivedCoins.Where(o => o.Outpoint.Hash.ToString() == desiredOutput.TransactionId && o.Outpoint.N == desiredOutput.OutputNumber).Any();
                    if (found)
                    {
                        // The output is still unspent which means no commitments is spent
                        return;
                    }
                }
            }

            // The output has not been found, which means it has been spent by a commitment
            outputs = await qBitNinjaApiCaller.GetAddressBalance(multisig, true, false);

            foreach (var op in outputs.Operations)
            {
                bool found = op.SpentCoins.
                             Where(sc => sc.Outpoint.Hash.ToString() == desiredOutput.TransactionId && sc.Outpoint.N == desiredOutput.OutputNumber).Any();

                if (found)
                {
                    var respectivePunishment = await FindThePunishment(op, desiredOutput);

                    if (respectivePunishment != null)
                    {
                        await rpcBitcoinClient.BroadcastTransaction(respectivePunishment, new Guid());
                    }
                    else
                    {
                        // The punishment has not been found
                    }
                }
            }
        }
コード例 #3
0
        public async Task <IActionResult> AddCommitmentPunishmentPairOldDesign([FromQuery] string commitment,
                                                                               [FromQuery] string punishment)
        {
            if (string.IsNullOrEmpty(commitment) || string.IsNullOrEmpty(punishment))
            {
                return(BadRequest("Passed parameters should not be null or empty"));
            }
            else
            {
                Transaction cTx = new Transaction(commitment);
                Transaction pTx = new Transaction(punishment);

                try
                {
                    using (OffchainMonitorContext context = new OffchainMonitorContext())
                    {
                        var newlyAddedCommitment = new CommitmentEntity
                        {
                            Commitment = commitment,
                            Punishment = punishment
                        };

                        bool found    = false;
                        var  multisig = await settingsRepository.Get <string>("multisig");

                        var netwok = await Helper.GetNetwork(settingsRepository);

                        for (int i = 0; i < cTx.Inputs.Count; i++)
                        {
                            var prevHash = cTx.Inputs[i].PrevOut.Hash.ToString();
                            var prevTx   = await bitcoinTransactionService.GetTransaction(prevHash);

                            var prevOut = cTx.Inputs[i].PrevOut;
                            if (prevTx.Outputs[prevOut.N].ScriptPubKey.GetDestinationAddress(netwok).ToString()
                                == multisig)
                            {
                                found = true;

                                var existingMultisigOutput = (from o in context.MultisigOutputs
                                                              where o.TransactionId == prevOut.Hash.ToString() && o.OutputNumber == prevOut.N
                                                              select o).FirstOrDefault();
                                if (existingMultisigOutput == null)
                                {
                                    var newMultisigOutput = new MultisigOutputEntity();
                                    newMultisigOutput.TransactionId = prevOut.Hash.ToString();
                                    newMultisigOutput.OutputNumber  = (int)prevOut.N;
                                    newMultisigOutput.LastSeen      = DateTime.UtcNow;
                                    await context.MultisigOutputs.AddAsync(newMultisigOutput);

                                    existingMultisigOutput = newMultisigOutput;
                                }

                                existingMultisigOutput.LastSeen = DateTime.UtcNow;
                                existingMultisigOutput.Commitments.Add(newlyAddedCommitment);

                                newlyAddedCommitment.CommitmentOutput = existingMultisigOutput;
                                await context.Commitments.AddAsync(newlyAddedCommitment);
                            }
                        }

                        if (!found)
                        {
                            return(BadRequest(string.Format("The provide transaction does not pay to multisig:{0}", multisig)));
                        }

                        await context.SaveChangesAsync();
                    }
                    return(Ok());
                }
                catch (Exception exp)
                {
                    throw exp;
                }
            }
        }