public void CanColorizeOutputs()
        {
            ColoredCoinTester tester = CreateTester(this.network, "CanColorizeIssuanceTransaction");

            ColoredTransaction colored1 = ColoredTransaction.FetchColors(tester.TestedTxId, tester.Repository);

            Assert.True(colored1.Inputs.Count == 0);
            Assert.True(colored1.Issuances.Count == 1);
            Assert.True(colored1.Transfers.Count == 0);
            Assert.Equal("Af59wop4VJjXk2DAzoX9scAUCcAsghPHFX", colored1.Issuances[0].Asset.Id.GetWif(this.network).ToString());

            tester = CreateTester(this.network, "CanColorizeTransferTransaction");
            ColoredTransaction colored2 = ColoredTransaction.FetchColors(tester.TestedTxId, tester.Repository);

            Assert.True(colored2.Inputs.Count == 1);
            Assert.True(colored2.Inputs[0].Asset == colored1.Issuances[0].Asset);
            Assert.True(colored2.Issuances.Count == 0);
            Assert.True(colored2.Transfers.Count == 2);
            Assert.Equal("Af59wop4VJjXk2DAzoX9scAUCcAsghPHFX", colored2.Transfers[0].Asset.Id.GetWif(this.network).ToString());

            tester = CreateTester(this.network, "CanColorizeTransferTransaction");
            Transaction tx = tester.Repository.Transactions.Get(tester.TestedTxId);

            //If there are less items in the  asset quantity list  than the number of colorable outputs (all the outputs except the marker output), the outputs in excess receive an asset quantity of zero.
            tx.Outputs.Add(new TxOut());
            tx.Outputs.Add(new TxOut());
            tx.Outputs.Add(new TxOut());
            tester.TestedTxId = tx.GetHash();
            tester.Repository.Transactions.Put(tester.TestedTxId, tx);
            colored2 = ColoredTransaction.FetchColors(tester.TestedTxId, tester.Repository);
            Assert.True(colored2.Inputs.Count == 1);
            Assert.True(colored2.Inputs[0].Asset == colored1.Issuances[0].Asset);
            Assert.True(colored2.Issuances.Count == 0);
            Assert.True(colored2.Transfers.Count == 2);
            Assert.Equal("Af59wop4VJjXk2DAzoX9scAUCcAsghPHFX", colored2.Transfers[0].Asset.Id.GetWif(this.network).ToString());
            AssetMoney[] destroyed = colored2.GetDestroyedAssets();
            Assert.True(destroyed.Length == 0);

            tester = CreateTester(this.network, "CanColorizeTransferTransaction");
            tx     = tester.Repository.Transactions.Get(tester.TestedTxId);
            //If there are more items in the  asset quantity list  than the number of colorable outputs, the transaction is deemed invalid, and all outputs are uncolored.
            ColorMarker payload = tx.GetColoredMarker();

            payload.Quantities         = payload.Quantities.Concat(new ulong[] { 1, 2 }).ToArray();
            tx.Outputs[0].ScriptPubKey = payload.GetScript();
            Assert.False(tx.HasValidColoredMarker());
            tester.TestedTxId = tx.GetHash();
            tester.Repository.Transactions.Put(tester.TestedTxId, tx);
            colored2 = ColoredTransaction.FetchColors(tester.TestedTxId, tester.Repository);
            Assert.True(colored2.Inputs.Count == 1);
            Assert.True(colored2.Issuances.Count == 0);
            Assert.True(colored2.Transfers.Count == 0);

            tester = CreateTester(this.network, "CanColorizeTransferTransaction");
            tx     = tester.Repository.Transactions.Get(tester.TestedTxId);
            //If the marker output is malformed, the transaction is invalid, and all outputs are uncolored.
            tx.Outputs[0].ScriptPubKey = new Script();
            tester.TestedTxId          = tx.GetHash();
            tester.Repository.Transactions.Put(tester.TestedTxId, tx);
            colored2 = ColoredTransaction.FetchColors(tester.TestedTxId, tester.Repository);
            Assert.True(colored2.Inputs.Count == 1);
            Assert.True(colored2.Issuances.Count == 0);
            Assert.True(colored2.Transfers.Count == 0);

            tester = CreateTester(this.network, "CanColorizeTransferTransaction");
            tx     = tester.Repository.Transactions.Get(tester.TestedTxId);
            //If there are less asset units in the input sequence than in the output sequence, the transaction is considered invalid and all outputs are uncolored.
            payload = tx.GetColoredMarker();
            payload.Quantities[0]      = 1001;
            tx.Outputs[0].ScriptPubKey = payload.GetScript();
            tester.TestedTxId          = tx.GetHash();
            tester.Repository.Transactions.Put(tester.TestedTxId, tx);
            colored2 = ColoredTransaction.FetchColors(tester.TestedTxId, tester.Repository);
            Assert.True(colored2.Inputs.Count == 1);
            Assert.True(colored2.Issuances.Count == 0);
            Assert.True(colored2.Transfers.Count == 0);

            tester = CreateTester(this.network, "CanColorizeTransferTransaction");
            tx     = tester.Repository.Transactions.Get(tester.TestedTxId);
            //If there are more asset units in the input sequence than in the output sequence, the transaction is considered valid
            payload = tx.GetColoredMarker();
            payload.Quantities[0]      = 999;
            tx.Outputs[0].ScriptPubKey = payload.GetScript();
            tester.TestedTxId          = tx.GetHash();
            tester.Repository.Transactions.Put(tester.TestedTxId, tx);
            colored2 = ColoredTransaction.FetchColors(tester.TestedTxId, tester.Repository);
            Assert.True(colored2.Inputs.Count == 1);
            Assert.True(colored2.Issuances.Count == 0);
            Assert.True(colored2.Transfers.Count == 2);
            destroyed = colored2.GetDestroyedAssets();
            Assert.True(destroyed.Length == 1);
            Assert.True(destroyed[0].Quantity == 1);
            Assert.True(destroyed[0].Id == colored2.Inputs[0].Asset.Id);

            //Verify that FetchColor update the repository
            var persistent = new NoSqlColoredTransactionRepository(Network.Main, tester.Repository.Transactions, new InMemoryNoSqlRepository(Network.Main));

            colored2 = ColoredTransaction.FetchColors(tester.TestedTxId, persistent);
            Assert.NotNull(persistent.Get(tester.TestedTxId));

            //Verify cached loadbulk correctly
            var cached = new CachedColoredTransactionRepository(persistent);

            persistent.Put(tester.TestedTxId, null);
            cached.WriteThrough = false;
            colored2            = ColoredTransaction.FetchColors(tester.TestedTxId, cached);
            cached.ReadThrough  = false;
            Assert.Null(cached.Get(tester.TestedTxId));            //Should not have written in the cache (cache outdated, thinking it is still null)
            Assert.NotNull(persistent.Get(tester.TestedTxId));     //But should have written in the inner repository
            Assert.NotNull(cached.Get(tx.Inputs[0].PrevOut.Hash)); //However, the previous transaction should have been loaded by loadbulk via ReadThrough
        }
Example #2
0
 public void RestoreMemento(TransactionBuildingContext memento)
 {
     _Marker        = memento._Marker == null ? null : new ColorMarker(memento._Marker.GetScript());
     Transaction    = memento.Transaction.Clone();
     AdditionalFees = memento.AdditionalFees;
 }