Ejemplo n.º 1
0
        public void TestDoubleSpend()
        {
            // prepare block
            var fakeHeaders      = new FakeHeaders();
            var chainedHeader0   = fakeHeaders.GenesisChained();
            var chainedHeader1   = fakeHeaders.NextChained();
            var chainedHeader2   = fakeHeaders.NextChained();
            var chain            = Chain.CreateForGenesisBlock(chainedHeader0).ToBuilder();
            var emptyCoinbaseTx0 = BlockTx.Create(0, Transaction.Create(0, ImmutableArray.Create <TxInput>(), ImmutableArray.Create <TxOutput>(), 0));
            var emptyCoinbaseTx1 = BlockTx.Create(0, Transaction.Create(1, ImmutableArray.Create <TxInput>(), ImmutableArray.Create <TxOutput>(), 0));

            // initialize memory utxo builder storage
            var memoryStorage          = new MemoryStorageManager();
            var memoryChainStateCursor = memoryStorage.OpenChainStateCursor().Item;

            memoryChainStateCursor.BeginTransaction();

            // initialize utxo builder
            var utxoBuilder = new UtxoBuilder();

            // prepare an unspent transaction
            var txHash      = new UInt256(100);
            var unspentTx   = new UnspentTx(txHash, chainedHeader1.Height, 0, 0, false, 1, OutputState.Unspent);
            var txOutputKey = new TxOutputKey(txHash, 0);
            var txOutput    = new TxOutput(0, ImmutableArray <byte> .Empty);

            // add the unspent transaction
            memoryChainStateCursor.TryAddUnspentTx(unspentTx);
            memoryChainStateCursor.TryAddUnspentTxOutput(txOutputKey, txOutput);

            // create an input to spend the unspent transaction
            var input = new TxInput(txHash, 0, ImmutableArray.Create <byte>(), 0);
            var tx    = BlockTx.Create(1, Transaction.Create(0, ImmutableArray.Create(input), ImmutableArray.Create <TxOutput>(), 0));

            // spend the input
            chain.AddBlock(chainedHeader1);
            utxoBuilder.CalculateUtxo(memoryChainStateCursor, chain.ToImmutable(), new[] { emptyCoinbaseTx0, tx }.ToBufferBlock()).ToEnumerable().ToList();

            // verify utxo storage
            UnspentTx actualUnspentTx; TxOutput actualTxOutput;

            Assert.IsTrue(memoryChainStateCursor.TryGetUnspentTx(txHash, out actualUnspentTx));
            Assert.IsTrue(actualUnspentTx.IsFullySpent);
            Assert.IsTrue(memoryChainStateCursor.TryGetUnspentTxOutput(txOutputKey, out actualTxOutput));
            Assert.AreEqual(txOutput, actualTxOutput);

            // attempt to spend the input again, validation exception should be thrown
            chain.AddBlock(chainedHeader2);
            AssertMethods.AssertAggregateThrows <ValidationException>(() =>
                                                                      utxoBuilder.CalculateUtxo(memoryChainStateCursor, chain.ToImmutable(), new[] { emptyCoinbaseTx1, tx }.ToBufferBlock()).ToEnumerable().ToList());
        }
Ejemplo n.º 2
0
        public void TestDoubleSpend()
        {
            // prepare block
            var fakeHeaders      = new FakeHeaders();
            var chainedHeader0   = fakeHeaders.GenesisChained();
            var chainedHeader1   = fakeHeaders.NextChained();
            var chain            = new ChainBuilder();
            var emptyCoinbaseTx0 = new Transaction(0, ImmutableArray.Create <TxInput>(), ImmutableArray.Create <TxOutput>(), 0);
            var emptyCoinbaseTx1 = new Transaction(1, ImmutableArray.Create <TxInput>(), ImmutableArray.Create <TxOutput>(), 0);

            // initialize memory utxo builder storage
            var memoryStorage          = new MemoryStorageManager();
            var memoryChainStateCursor = memoryStorage.OpenChainStateCursor().Item;

            // initialize utxo builder
            var utxoBuilder = new UtxoBuilder(memoryChainStateCursor, LogManager.CreateNullLogger());

            // prepare an unspent transaction
            var txHash    = new UInt256(100);
            var unspentTx = new UnspentTx(txHash, chainedHeader0.Height, 0, 1, OutputState.Unspent);

            // add the unspent transaction
            memoryChainStateCursor.TryAddUnspentTx(unspentTx);

            // create an input to spend the unspent transaction
            var input = new TxInput(new TxOutputKey(txHash, txOutputIndex: 0), ImmutableArray.Create <byte>(), 0);
            var tx    = new Transaction(0, ImmutableArray.Create(input), ImmutableArray.Create <TxOutput>(), 0);

            // spend the input
            chain.AddBlock(chainedHeader0);
            utxoBuilder.CalculateUtxo(chain.ToImmutable(), new[] { emptyCoinbaseTx0, tx }).ToList();

            // verify utxo storage
            Assert.IsFalse(memoryChainStateCursor.ContainsUnspentTx(txHash));

            // attempt to spend the input again
            chain.AddBlock(chainedHeader1);
            utxoBuilder.CalculateUtxo(chain.ToImmutable(), new[] { emptyCoinbaseTx1, tx }).ToList();

            // validation exception should be thrown
        }
Ejemplo n.º 3
0
        public void TestSimpleSpend()
        {
            // prepare block
            var fakeHeaders      = new FakeHeaders();
            var chainedHeader0   = fakeHeaders.GenesisChained();
            var chainedHeader1   = fakeHeaders.NextChained();
            var chainedHeader2   = fakeHeaders.NextChained();
            var chain            = new ChainBuilder();
            var emptyCoinbaseTx0 = new Transaction(0, ImmutableArray.Create <TxInput>(), ImmutableArray.Create <TxOutput>(), 0);
            var emptyCoinbaseTx1 = new Transaction(1, ImmutableArray.Create <TxInput>(), ImmutableArray.Create <TxOutput>(), 0);
            var emptyCoinbaseTx2 = new Transaction(2, ImmutableArray.Create <TxInput>(), ImmutableArray.Create <TxOutput>(), 0);

            // initialize memory utxo builder storage
            var memoryStorage          = new MemoryStorageManager();
            var memoryChainStateCursor = memoryStorage.OpenChainStateCursor().Item;

            // initialize utxo builder
            var utxoBuilder = new UtxoBuilder(memoryChainStateCursor, LogManager.CreateNullLogger());

            // prepare an unspent transaction
            var txHash    = new UInt256(100);
            var unspentTx = new UnspentTx(txHash, chainedHeader0.Height, 0, 3, OutputState.Unspent);

            // prepare unspent output
            var unspentTransactions = ImmutableDictionary.Create <UInt256, UnspentTx>().Add(txHash, unspentTx);

            // add the unspent transaction
            memoryChainStateCursor.TryAddUnspentTx(unspentTx);

            // create an input to spend the unspent transaction's first output
            var input0 = new TxInput(new TxOutputKey(txHash, txOutputIndex: 0), ImmutableArray.Create <byte>(), 0);
            var tx0    = new Transaction(0, ImmutableArray.Create(input0), ImmutableArray.Create <TxOutput>(), 0);

            // spend the input
            chain.AddBlock(chainedHeader0);
            utxoBuilder.CalculateUtxo(chain.ToImmutable(), new[] { emptyCoinbaseTx0, tx0 }).ToList();

            // verify utxo storage
            UnspentTx actualUnspentTx;

            Assert.IsTrue(memoryChainStateCursor.TryGetUnspentTx(txHash, out actualUnspentTx));
            Assert.IsTrue(actualUnspentTx.OutputStates.Length == 3);
            Assert.IsTrue(actualUnspentTx.OutputStates[0] == OutputState.Spent);
            Assert.IsTrue(actualUnspentTx.OutputStates[1] == OutputState.Unspent);
            Assert.IsTrue(actualUnspentTx.OutputStates[2] == OutputState.Unspent);

            // create an input to spend the unspent transaction's second output
            var input1 = new TxInput(new TxOutputKey(txHash, txOutputIndex: 1), ImmutableArray.Create <byte>(), 0);
            var tx1    = new Transaction(0, ImmutableArray.Create(input1), ImmutableArray.Create <TxOutput>(), 0);

            // spend the input
            chain.AddBlock(chainedHeader1);
            utxoBuilder.CalculateUtxo(chain.ToImmutable(), new[] { emptyCoinbaseTx1, tx1 }).ToList();

            // verify utxo storage
            Assert.IsTrue(memoryChainStateCursor.TryGetUnspentTx(txHash, out actualUnspentTx));
            Assert.IsTrue(actualUnspentTx.OutputStates.Length == 3);
            Assert.IsTrue(actualUnspentTx.OutputStates[0] == OutputState.Spent);
            Assert.IsTrue(actualUnspentTx.OutputStates[1] == OutputState.Spent);
            Assert.IsTrue(actualUnspentTx.OutputStates[2] == OutputState.Unspent);

            // create an input to spend the unspent transaction's third output
            var input2 = new TxInput(new TxOutputKey(txHash, txOutputIndex: 2), ImmutableArray.Create <byte>(), 0);
            var tx2    = new Transaction(0, ImmutableArray.Create(input2), ImmutableArray.Create <TxOutput>(), 0);

            // spend the input
            chain.AddBlock(chainedHeader2);
            utxoBuilder.CalculateUtxo(chain.ToImmutable(), new[] { emptyCoinbaseTx2, tx2 }).ToList();

            // verify utxo storage
            Assert.IsFalse(memoryChainStateCursor.ContainsUnspentTx(txHash));
        }
Ejemplo n.º 4
0
        public void TestSimpleSpend()
        {
            // prepare block
            var fakeHeaders      = new FakeHeaders();
            var chainedHeader0   = fakeHeaders.GenesisChained();
            var chainedHeader1   = fakeHeaders.NextChained();
            var chainedHeader2   = fakeHeaders.NextChained();
            var chainedHeader3   = fakeHeaders.NextChained();
            var chain            = Chain.CreateForGenesisBlock(chainedHeader0).ToBuilder();
            var emptyCoinbaseTx0 = BlockTx.Create(0, Transaction.Create(0, ImmutableArray.Create <TxInput>(), ImmutableArray.Create <TxOutput>(), 0));
            var emptyCoinbaseTx1 = BlockTx.Create(1, Transaction.Create(1, ImmutableArray.Create <TxInput>(), ImmutableArray.Create <TxOutput>(), 0));
            var emptyCoinbaseTx2 = BlockTx.Create(2, Transaction.Create(2, ImmutableArray.Create <TxInput>(), ImmutableArray.Create <TxOutput>(), 0));

            // initialize memory utxo builder storage
            var memoryStorage          = new MemoryStorageManager();
            var memoryChainStateCursor = memoryStorage.OpenChainStateCursor().Item;

            memoryChainStateCursor.BeginTransaction();

            // initialize utxo builder
            var utxoBuilder = new UtxoBuilder();

            // prepare an unspent transaction
            var txHash       = new UInt256(100);
            var unspentTx    = new UnspentTx(txHash, chainedHeader1.Height, 0, 0, false, 3, OutputState.Unspent);
            var txOutput1Key = new TxOutputKey(txHash, 0);
            var txOutput1    = new TxOutput(0, ImmutableArray <byte> .Empty);
            var txOutput2Key = new TxOutputKey(txHash, 1);
            var txOutput2    = new TxOutput(1, ImmutableArray <byte> .Empty);
            var txOutput3Key = new TxOutputKey(txHash, 2);
            var txOutput3    = new TxOutput(2, ImmutableArray <byte> .Empty);

            // prepare unspent output
            var unspentTransactions = ImmutableDictionary.Create <UInt256, UnspentTx>().Add(txHash, unspentTx);

            // add the unspent transaction
            memoryChainStateCursor.TryAddUnspentTx(unspentTx);
            memoryChainStateCursor.TryAddUnspentTxOutput(txOutput1Key, txOutput1);
            memoryChainStateCursor.TryAddUnspentTxOutput(txOutput2Key, txOutput2);
            memoryChainStateCursor.TryAddUnspentTxOutput(txOutput3Key, txOutput3);

            // create an input to spend the unspent transaction's first output
            var input0 = new TxInput(txHash, 0, ImmutableArray.Create <byte>(), 0);
            var tx0    = BlockTx.Create(1, Transaction.Create(0, ImmutableArray.Create(input0), ImmutableArray.Create <TxOutput>(), 0));

            // spend the input
            chain.AddBlock(chainedHeader1);
            utxoBuilder.CalculateUtxo(memoryChainStateCursor, chain.ToImmutable(), new[] { emptyCoinbaseTx0, tx0 }.ToBufferBlock()).ToEnumerable().ToList();

            // verify utxo storage
            UnspentTx actualUnspentTx; TxOutput actualTxOutput;

            Assert.IsTrue(memoryChainStateCursor.TryGetUnspentTx(txHash, out actualUnspentTx));
            Assert.IsTrue(actualUnspentTx.OutputStates.Length == 3);
            Assert.IsTrue(actualUnspentTx.OutputStates[0] == OutputState.Spent);
            Assert.IsTrue(actualUnspentTx.OutputStates[1] == OutputState.Unspent);
            Assert.IsTrue(actualUnspentTx.OutputStates[2] == OutputState.Unspent);

            Assert.IsTrue(memoryChainStateCursor.TryGetUnspentTxOutput(txOutput1Key, out actualTxOutput));
            Assert.AreEqual(txOutput1, actualTxOutput);
            Assert.IsTrue(memoryChainStateCursor.TryGetUnspentTxOutput(txOutput2Key, out actualTxOutput));
            Assert.AreEqual(txOutput2, actualTxOutput);
            Assert.IsTrue(memoryChainStateCursor.TryGetUnspentTxOutput(txOutput3Key, out actualTxOutput));
            Assert.AreEqual(txOutput3, actualTxOutput);

            // create an input to spend the unspent transaction's second output
            var input1 = new TxInput(txHash, 1, ImmutableArray.Create <byte>(), 0);
            var tx1    = BlockTx.Create(1, Transaction.Create(0, ImmutableArray.Create(input1), ImmutableArray.Create <TxOutput>(), 0));

            // spend the input
            chain.AddBlock(chainedHeader2);
            utxoBuilder.CalculateUtxo(memoryChainStateCursor, chain.ToImmutable(), new[] { emptyCoinbaseTx1, tx1 }.ToBufferBlock()).ToEnumerable().ToList();

            // verify utxo storage
            Assert.IsTrue(memoryChainStateCursor.TryGetUnspentTx(txHash, out actualUnspentTx));
            Assert.IsTrue(actualUnspentTx.OutputStates.Length == 3);
            Assert.IsTrue(actualUnspentTx.OutputStates[0] == OutputState.Spent);
            Assert.IsTrue(actualUnspentTx.OutputStates[1] == OutputState.Spent);
            Assert.IsTrue(actualUnspentTx.OutputStates[2] == OutputState.Unspent);

            // create an input to spend the unspent transaction's third output
            var input2 = new TxInput(txHash, 2, ImmutableArray.Create <byte>(), 0);
            var tx2    = BlockTx.Create(2, Transaction.Create(0, ImmutableArray.Create(input2), ImmutableArray.Create <TxOutput>(), 0));

            // spend the input
            chain.AddBlock(chainedHeader3);
            utxoBuilder.CalculateUtxo(memoryChainStateCursor, chain.ToImmutable(), new[] { emptyCoinbaseTx2, tx2 }.ToBufferBlock()).ToEnumerable().ToList();

            // verify utxo storage
            Assert.IsTrue(memoryChainStateCursor.TryGetUnspentTx(txHash, out actualUnspentTx));
            Assert.IsTrue(actualUnspentTx.IsFullySpent);
        }