Ejemplo n.º 1
0
        public void TestShorterChainWins()
        {
            //TODO MemoryBlockchain.ChooseNewWinner non-determinism is causing this to fail

            // create the first blockchain
            var blockchain = new MemoryBlockchain();

            // add some simple blocks
            var block1  = blockchain.MineAndAddEmptyBlock(blockchain.GenesisChainedBlock);
            var block2  = blockchain.MineAndAddEmptyBlock(block1.Item2);
            var block3a = blockchain.MineAndAddEmptyBlock(block2.Item2);
            var block4a = blockchain.MineAndAddEmptyBlock(block3a.Item2);
            var block5a = blockchain.MineAndAddEmptyBlock(block4a.Item2);

            // check
            Assert.AreEqual(5, blockchain.CurrentBlockchain.Height);
            Assert.AreEqual(block5a.Item1.Hash, blockchain.CurrentBlockchain.RootBlockHash);
            //TODO Assert.AreEqual(5, blockchain.CurrentBlockchain.Utxo.Count);

            // create a split with 3b, but do more work than current height 5 chain
            blockchain.Rules.SetHighestTarget(UnitTestRules.Target2);
            var block3b = blockchain.MineAndAddEmptyBlock(block2.Item2);

            // check that blockchain reorganized to shorter chain
            Assert.AreEqual(3, blockchain.CurrentBlockchain.Height);
            Assert.AreEqual(block3b.Item1.Hash, blockchain.CurrentBlockchain.RootBlockHash);
            //TODO Assert.AreEqual(5, blockchain.CurrentBlockchain.Utxo.Count);
        }
Ejemplo n.º 2
0
        public void TestAddSingleBlock()
        {
            var blockchain = new MemoryBlockchain();

            var block = blockchain.MineAndAddEmptyBlock(blockchain.GenesisChainedBlock).Item1;

            Assert.AreEqual(1, blockchain.CurrentBlockchain.Height);
            Assert.AreEqual(block.Hash, blockchain.CurrentBlockchain.RootBlockHash);
        }
Ejemplo n.º 3
0
        public void TestAddSingleBlock()
        {
            var blockchain = new MemoryBlockchain();

            var block = blockchain.MineAndAddEmptyBlock(blockchain.GenesisChainedBlock).Item1;

            Assert.AreEqual(1, blockchain.CurrentBlockchain.Height);
            Assert.AreEqual(block.Hash, blockchain.CurrentBlockchain.RootBlockHash);
        }
Ejemplo n.º 4
0
        public void TestDoubleSpend()
        {
            var blockchain = new MemoryBlockchain();

            // create a new keypair to spend to
            var toKeyPair    = TransactionManager.CreateKeyPair();
            var toPrivateKey = toKeyPair.Item1;
            var toPublicKey  = toKeyPair.Item2;

            // create a new keypair to double spend to
            var toKeyPairBad    = TransactionManager.CreateKeyPair();
            var toPrivateKeyBad = toKeyPair.Item1;
            var toPublicKeyBad  = toKeyPair.Item2;

            // add some simple blocks
            var block1 = blockchain.MineAndAddEmptyBlock(blockchain.GenesisChainedBlock);
            var block2 = blockchain.MineAndAddEmptyBlock(block1.Item2);

            // check
            Assert.AreEqual(2, blockchain.CurrentBlockchain.Height);
            Assert.AreEqual(block2.Item1.Hash, blockchain.CurrentBlockchain.RootBlockHash);
            Assert.AreEqual(2, blockchain.CurrentBlockchain.Utxo.Count);

            // spend block 2's coinbase in block 3
            var block3Block = blockchain.CreateEmptyBlock(block2.Item2);
            var spendTx     = TransactionManager.CreateSpendTransaction(block2.Item1.Transactions[0], 0, (byte)ScriptHashType.SIGHASH_ALL, 50 * SATOSHI_PER_BTC, blockchain.CoinbasePrivateKey, blockchain.CoinbasePublicKey, toPublicKey);

            block3Block = block3Block.WithAddedTransactions(spendTx);
            var block3 = blockchain.MineAndAddBlock(block3Block, block2.Item2);

            // check
            Assert.AreEqual(3, blockchain.CurrentBlockchain.Height);
            Assert.AreEqual(block3.Item1.Hash, blockchain.CurrentBlockchain.RootBlockHash);
            Assert.AreEqual(3, blockchain.CurrentBlockchain.Utxo.Count);

            // attempt to spend block 2's coinbase again in block 4
            var block4BadBlock = blockchain.CreateEmptyBlock(block3.Item2);
            var doubleSpendTx  = TransactionManager.CreateSpendTransaction(block2.Item1.Transactions[0], 0, (byte)ScriptHashType.SIGHASH_ALL, 50 * SATOSHI_PER_BTC, blockchain.CoinbasePrivateKey, blockchain.CoinbasePublicKey, toPublicKeyBad);

            block4BadBlock = block4BadBlock.WithAddedTransactions(doubleSpendTx);
            var block4Bad = blockchain.MineAndAddBlock(block4BadBlock, block3.Item2);

            // check that bad block wasn't added
            Assert.AreEqual(3, blockchain.CurrentBlockchain.Height);
            Assert.AreEqual(block3.Item1.Hash, blockchain.CurrentBlockchain.RootBlockHash);
            Assert.AreEqual(3, blockchain.CurrentBlockchain.Utxo.Count);

            // add a simple block
            var block4 = blockchain.MineAndAddEmptyBlock(block3.Item2);

            // check
            Assert.AreEqual(4, blockchain.CurrentBlockchain.Height);
            Assert.AreEqual(block4.Item1.Hash, blockchain.CurrentBlockchain.RootBlockHash);
            Assert.AreEqual(4, blockchain.CurrentBlockchain.Utxo.Count);
        }
Ejemplo n.º 5
0
        public void TestDoubleSpend()
        {
            var blockchain = new MemoryBlockchain();

            // create a new keypair to spend to
            var toKeyPair = TransactionManager.CreateKeyPair();
            var toPrivateKey = toKeyPair.Item1;
            var toPublicKey = toKeyPair.Item2;

            // create a new keypair to double spend to
            var toKeyPairBad = TransactionManager.CreateKeyPair();
            var toPrivateKeyBad = toKeyPair.Item1;
            var toPublicKeyBad = toKeyPair.Item2;

            // add some simple blocks
            var block1 = blockchain.MineAndAddEmptyBlock(blockchain.GenesisChainedBlock);
            var block2 = blockchain.MineAndAddEmptyBlock(block1.Item2);

            // check
            Assert.AreEqual(2, blockchain.CurrentBlockchain.Height);
            Assert.AreEqual(block2.Item1.Hash, blockchain.CurrentBlockchain.RootBlockHash);
            Assert.AreEqual(2, blockchain.CurrentBlockchain.Utxo.Count);

            // spend block 2's coinbase in block 3
            var block3Block = blockchain.CreateEmptyBlock(block2.Item2);
            var spendTx = TransactionManager.CreateSpendTransaction(block2.Item1.Transactions[0], 0, (byte)ScriptHashType.SIGHASH_ALL, 50 * SATOSHI_PER_BTC, blockchain.CoinbasePrivateKey, blockchain.CoinbasePublicKey, toPublicKey);
            block3Block = block3Block.WithAddedTransactions(spendTx);
            var block3 = blockchain.MineAndAddBlock(block3Block, block2.Item2);

            // check
            Assert.AreEqual(3, blockchain.CurrentBlockchain.Height);
            Assert.AreEqual(block3.Item1.Hash, blockchain.CurrentBlockchain.RootBlockHash);
            Assert.AreEqual(3, blockchain.CurrentBlockchain.Utxo.Count);

            // attempt to spend block 2's coinbase again in block 4
            var block4BadBlock = blockchain.CreateEmptyBlock(block3.Item2);
            var doubleSpendTx = TransactionManager.CreateSpendTransaction(block2.Item1.Transactions[0], 0, (byte)ScriptHashType.SIGHASH_ALL, 50 * SATOSHI_PER_BTC, blockchain.CoinbasePrivateKey, blockchain.CoinbasePublicKey, toPublicKeyBad);
            block4BadBlock = block4BadBlock.WithAddedTransactions(doubleSpendTx);
            var block4Bad = blockchain.MineAndAddBlock(block4BadBlock, block3.Item2);

            // check that bad block wasn't added
            Assert.AreEqual(3, blockchain.CurrentBlockchain.Height);
            Assert.AreEqual(block3.Item1.Hash, blockchain.CurrentBlockchain.RootBlockHash);
            Assert.AreEqual(3, blockchain.CurrentBlockchain.Utxo.Count);

            // add a simple block
            var block4 = blockchain.MineAndAddEmptyBlock(block3.Item2);

            // check
            Assert.AreEqual(4, blockchain.CurrentBlockchain.Height);
            Assert.AreEqual(block4.Item1.Hash, blockchain.CurrentBlockchain.RootBlockHash);
            Assert.AreEqual(4, blockchain.CurrentBlockchain.Utxo.Count);
        }
Ejemplo n.º 6
0
        public void TestLongBlockchain()
        {
            var blockchain = new MemoryBlockchain();

            var count = 1.THOUSAND();

            var chainedBlock = blockchain.GenesisChainedBlock;

            for (var i = 0; i < count; i++)
            {
                Debug.WriteLine("TestLongBlockchain mining block {0:#,##0}".Format2(i));
                chainedBlock = blockchain.MineAndAddEmptyBlock(chainedBlock).Item2;
            }

            Assert.AreEqual(count, blockchain.CurrentBlockchain.Height);
            Assert.AreEqual(chainedBlock.BlockHash, blockchain.CurrentBlockchain.RootBlockHash);
        }
Ejemplo n.º 7
0
        public void TestSimpleBlockchainSplit()
        {
            //TODO MemoryBlockchain.ChooseNewWinner non-determinism is causing this to fail

            // create the first blockchain
            var blockchain1 = new MemoryBlockchain();

            // add some simple blocks
            var block1 = blockchain1.MineAndAddEmptyBlock(blockchain1.GenesisChainedBlock);
            var block2 = blockchain1.MineAndAddEmptyBlock(block1.Item2);

            // introduce a split, do more work on 3a
            blockchain1.Rules.SetHighestTarget(UnitTestRules.Target1);
            var block3a = blockchain1.MineAndAddEmptyBlock(block2.Item2);

            blockchain1.Rules.SetHighestTarget(UnitTestRules.Target0);
            var block3b = blockchain1.MineAndAddEmptyBlock(block2.Item2);

            // check that 3a is current as it has more work
            Assert.AreEqual(3, blockchain1.CurrentBlockchain.Height);
            Assert.AreEqual(block3a.Item1.Hash, blockchain1.CurrentBlockchain.RootBlockHash);
            //TODO Assert.AreEqual(3, blockchain1.CurrentBlockchain.Utxo.Count);

            // continue split
            var block4a = blockchain1.MineAndAddEmptyBlock(block3a.Item2);
            var block4b = blockchain1.MineAndAddEmptyBlock(block3b.Item2);

            // check
            Assert.AreEqual(4, blockchain1.CurrentBlockchain.Height);
            Assert.AreEqual(block4a.Item1.Hash, blockchain1.CurrentBlockchain.RootBlockHash);
            //TODO Assert.AreEqual(4, blockchain1.CurrentBlockchain.Utxo.Count);

            // resolve split, with other chain winning
            blockchain1.Rules.SetHighestTarget(UnitTestRules.Target1);
            var block5b = blockchain1.MineAndAddEmptyBlock(block4b.Item2);

            // check that blockchain reorged to the winning chain
            Assert.AreEqual(5, blockchain1.CurrentBlockchain.Height);
            Assert.AreEqual(block5b.Item1.Hash, blockchain1.CurrentBlockchain.RootBlockHash);
            //TODO Assert.AreEqual(5, blockchain1.CurrentBlockchain.Utxo.Count);

            // continue on winning fork
            var block6b = blockchain1.MineAndAddEmptyBlock(block5b.Item2);

            // check that blockchain reorged to the winning chain
            Assert.AreEqual(6, blockchain1.CurrentBlockchain.Height);
            Assert.AreEqual(block6b.Item1.Hash, blockchain1.CurrentBlockchain.RootBlockHash);
            //TODO Assert.AreEqual(5, blockchain1.CurrentBlockchain.Utxo.Count);

            // create a second blockchain, reusing the genesis from the first
            var blockchain2 = new MemoryBlockchain(blockchain1.GenesisBlock);

            // add only the winning blocks to the second blockchain
            blockchain2.AddBlock(block1.Item1, blockchain2.GenesisChainedBlock);
            blockchain2.AddBlock(block2.Item1, block1.Item2);
            blockchain2.AddBlock(block3b.Item1, block2.Item2);
            blockchain2.AddBlock(block4b.Item1, block3b.Item2);
            blockchain2.AddBlock(block5b.Item1, block4b.Item2);
            blockchain2.AddBlock(block6b.Item1, block5b.Item2);

            // check second blockchain
            Assert.AreEqual(6, blockchain2.CurrentBlockchain.Height);
            Assert.AreEqual(block6b.Item1.Hash, blockchain2.CurrentBlockchain.RootBlockHash);
            //TODO Assert.AreEqual(5, blockchain2.CurrentBlockchain.Utxo.Count);

            // verify that re-organized blockchain matches winning-only blockchain
            var actualUtxo   = blockchain1.CurrentBlockchain.Utxo;
            var expectedUtxo = blockchain2.CurrentBlockchain.Utxo;

            Assert.IsTrue(expectedUtxo.SequenceEqual(actualUtxo));
        }
Ejemplo n.º 8
0
        public void TestLongBlockchain()
        {
            var blockchain = new MemoryBlockchain();

            var count = 1.THOUSAND();

            var chainedBlock = blockchain.GenesisChainedBlock;
            for (var i = 0; i < count; i++)
            {
                Debug.WriteLine("TestLongBlockchain mining block {0:#,##0}".Format2(i));
                chainedBlock = blockchain.MineAndAddEmptyBlock(chainedBlock).Item2;
            }

            Assert.AreEqual(count, blockchain.CurrentBlockchain.Height);
            Assert.AreEqual(chainedBlock.BlockHash, blockchain.CurrentBlockchain.RootBlockHash);
        }
Ejemplo n.º 9
0
        public void TestSimpleBlockchainSplit()
        {
            //TODO MemoryBlockchain.ChooseNewWinner non-determinism is causing this to fail

            // create the first blockchain
            var blockchain1 = new MemoryBlockchain();

            // add some simple blocks
            var block1 = blockchain1.MineAndAddEmptyBlock(blockchain1.GenesisChainedBlock);
            var block2 = blockchain1.MineAndAddEmptyBlock(block1.Item2);

            // introduce a split, do more work on 3a
            blockchain1.Rules.SetHighestTarget(UnitTestRules.Target1);
            var block3a = blockchain1.MineAndAddEmptyBlock(block2.Item2);
            blockchain1.Rules.SetHighestTarget(UnitTestRules.Target0);
            var block3b = blockchain1.MineAndAddEmptyBlock(block2.Item2);

            // check that 3a is current as it has more work
            Assert.AreEqual(3, blockchain1.CurrentBlockchain.Height);
            Assert.AreEqual(block3a.Item1.Hash, blockchain1.CurrentBlockchain.RootBlockHash);
            //TODO Assert.AreEqual(3, blockchain1.CurrentBlockchain.Utxo.Count);

            // continue split
            var block4a = blockchain1.MineAndAddEmptyBlock(block3a.Item2);
            var block4b = blockchain1.MineAndAddEmptyBlock(block3b.Item2);

            // check
            Assert.AreEqual(4, blockchain1.CurrentBlockchain.Height);
            Assert.AreEqual(block4a.Item1.Hash, blockchain1.CurrentBlockchain.RootBlockHash);
            //TODO Assert.AreEqual(4, blockchain1.CurrentBlockchain.Utxo.Count);

            // resolve split, with other chain winning
            blockchain1.Rules.SetHighestTarget(UnitTestRules.Target1);
            var block5b = blockchain1.MineAndAddEmptyBlock(block4b.Item2);

            // check that blockchain reorged to the winning chain
            Assert.AreEqual(5, blockchain1.CurrentBlockchain.Height);
            Assert.AreEqual(block5b.Item1.Hash, blockchain1.CurrentBlockchain.RootBlockHash);
            //TODO Assert.AreEqual(5, blockchain1.CurrentBlockchain.Utxo.Count);

            // continue on winning fork
            var block6b = blockchain1.MineAndAddEmptyBlock(block5b.Item2);

            // check that blockchain reorged to the winning chain
            Assert.AreEqual(6, blockchain1.CurrentBlockchain.Height);
            Assert.AreEqual(block6b.Item1.Hash, blockchain1.CurrentBlockchain.RootBlockHash);
            //TODO Assert.AreEqual(5, blockchain1.CurrentBlockchain.Utxo.Count);

            // create a second blockchain, reusing the genesis from the first
            var blockchain2 = new MemoryBlockchain(blockchain1.GenesisBlock);

            // add only the winning blocks to the second blockchain
            blockchain2.AddBlock(block1.Item1, blockchain2.GenesisChainedBlock);
            blockchain2.AddBlock(block2.Item1, block1.Item2);
            blockchain2.AddBlock(block3b.Item1, block2.Item2);
            blockchain2.AddBlock(block4b.Item1, block3b.Item2);
            blockchain2.AddBlock(block5b.Item1, block4b.Item2);
            blockchain2.AddBlock(block6b.Item1, block5b.Item2);

            // check second blockchain
            Assert.AreEqual(6, blockchain2.CurrentBlockchain.Height);
            Assert.AreEqual(block6b.Item1.Hash, blockchain2.CurrentBlockchain.RootBlockHash);
            //TODO Assert.AreEqual(5, blockchain2.CurrentBlockchain.Utxo.Count);

            // verify that re-organized blockchain matches winning-only blockchain
            var actualUtxo = blockchain1.CurrentBlockchain.Utxo;
            var expectedUtxo = blockchain2.CurrentBlockchain.Utxo;

            Assert.IsTrue(expectedUtxo.SequenceEqual(actualUtxo));
        }
Ejemplo n.º 10
0
        public void TestShorterChainWins()
        {
            //TODO MemoryBlockchain.ChooseNewWinner non-determinism is causing this to fail

            // create the first blockchain
            var blockchain = new MemoryBlockchain();

            // add some simple blocks
            var block1 = blockchain.MineAndAddEmptyBlock(blockchain.GenesisChainedBlock);
            var block2 = blockchain.MineAndAddEmptyBlock(block1.Item2);
            var block3a = blockchain.MineAndAddEmptyBlock(block2.Item2);
            var block4a = blockchain.MineAndAddEmptyBlock(block3a.Item2);
            var block5a = blockchain.MineAndAddEmptyBlock(block4a.Item2);

            // check
            Assert.AreEqual(5, blockchain.CurrentBlockchain.Height);
            Assert.AreEqual(block5a.Item1.Hash, blockchain.CurrentBlockchain.RootBlockHash);
            //TODO Assert.AreEqual(5, blockchain.CurrentBlockchain.Utxo.Count);

            // create a split with 3b, but do more work than current height 5 chain
            blockchain.Rules.SetHighestTarget(UnitTestRules.Target2);
            var block3b = blockchain.MineAndAddEmptyBlock(block2.Item2);

            // check that blockchain reorganized to shorter chain
            Assert.AreEqual(3, blockchain.CurrentBlockchain.Height);
            Assert.AreEqual(block3b.Item1.Hash, blockchain.CurrentBlockchain.RootBlockHash);
            //TODO Assert.AreEqual(5, blockchain.CurrentBlockchain.Utxo.Count);
        }