Ejemplo n.º 1
0
        internal RuleList GetBlocksToTest(bool addSigExpensiveBlocks, bool runLargeReorgs)
        {
            List <Rule> blocks = new List <Rule>();
            RuleList    ret    = new RuleList(blocks, hashHeaderMap, 10);

            Queue <TransactionOutPointWithValue> spendableOutputs = new Queue <TransactionOutPointWithValue>();

            int   chainHeadHeight = 1;
            Block chainHead       = Network.GetGenesis().CreateNextBlockWithCoinbase(coinbaseOutKeyPubKey, Money.Parse("50"));

            blocks.Add(new BlockAndValidity(blockToHeightMap, hashHeaderMap, chainHead, true, false, chainHead.GetHash(), 1, "Initial Block"));

            spendableOutputs.Enqueue(new TransactionOutPointWithValue(
                                         new OutPoint(chainHead.Transactions[0].GetHash(), 0),
                                         Money.Parse("50"), chainHead.Transactions[0].Outputs[0].ScriptPubKey));

            for (int i = 1; i < Network.SpendableCoinbaseDepth; i++)
            {
                chainHead = chainHead.CreateNextBlockWithCoinbase(coinbaseOutKeyPubKey, Money.Parse("50"));
                chainHeadHeight++;
                blocks.Add(new BlockAndValidity(blockToHeightMap, hashHeaderMap, chainHead, true, false, chainHead.GetHash(), i + 1, "Initial Block chain output generation"));
                spendableOutputs.Enqueue(new TransactionOutPointWithValue(
                                             new OutPoint(chainHead.Transactions[0].GetHash(), 0),
                                             Money.Parse("50"), chainHead.Transactions.First().Outputs.First().ScriptPubKey));
            }

            // Start by building a couple of blocks on top of the genesis block.
            Block b1 = createNextBlock(chainHead, chainHeadHeight + 1, spendableOutputs.Dequeue(), null);

            blocks.Add(new BlockAndValidity(blockToHeightMap, hashHeaderMap, b1, true, false, b1.GetHash(), chainHeadHeight + 1, "b1"));
            spendableOutputs.Enqueue(new TransactionOutPointWithValue(
                                         new OutPoint(b1.Transactions[0].GetHash(), 0),
                                         b1.Transactions[0].Outputs[0].Value,
                                         b1.Transactions[0].Outputs[0].ScriptPubKey));

            TransactionOutPointWithValue out1 = spendableOutputs.Dequeue();

            Assert.True(out1 != null);
            Block b2 = createNextBlock(b1, chainHeadHeight + 2, out1, null);

            blocks.Add(new BlockAndValidity(blockToHeightMap, hashHeaderMap, b2, true, false, b2.GetHash(), chainHeadHeight + 2, "b2"));
            // Make sure nothing funky happens if we try to re-add b2
            blocks.Add(new BlockAndValidity(blockToHeightMap, hashHeaderMap, b2, true, false, b2.GetHash(), chainHeadHeight + 2, "b2"));
            spendableOutputs.Enqueue(new TransactionOutPointWithValue(
                                         new OutPoint(b2.Transactions[0].GetHash(), 0),
                                         b2.Transactions[0].Outputs[0].Value,
                                         b2.Transactions[0].Outputs[0].ScriptPubKey));
            // We now have the following chain (which output is spent is in parentheses):
            // genesis -> b1 (0) -> b2 (1)
            //
            // so fork like this:
            //
            // genesis -> b1 (0) -> b2 (1)
            // \-> b3 (1)
            //
            // Nothing should happen at this point. We saw b2 first so it takes priority.
            Block b3 = createNextBlock(b1, chainHeadHeight + 2, out1, null);

            blocks.Add(new BlockAndValidity(blockToHeightMap, hashHeaderMap, b3, true, false, b2.GetHash(), chainHeadHeight + 2, "b3"));
            // Make sure nothing breaks if we add b3 twice
            blocks.Add(new BlockAndValidity(blockToHeightMap, hashHeaderMap, b3, true, false, b2.GetHash(), chainHeadHeight + 2, "b3"));
            // Now we add another block to make the alternative chain longer.
            TransactionOutPointWithValue out2 = spendableOutputs.Dequeue();

            Assert.True(out2 != null);

            Block b4 = createNextBlock(b3, chainHeadHeight + 3, out2, null);

            blocks.Add(new BlockAndValidity(blockToHeightMap, hashHeaderMap, b4, true, false, b4.GetHash(), chainHeadHeight + 3, "b4"));


            //
            // genesis -> b1 (0) -> b2 (1)
            // \-> b3 (1) -> b4 (2)
            //
            // ... and back to the first chain.
            Block b5 = createNextBlock(b2, chainHeadHeight + 3, out2, null);

            blocks.Add(new BlockAndValidity(blockToHeightMap, hashHeaderMap, b5, true, false, b4.GetHash(), chainHeadHeight + 3, "b5"));
            spendableOutputs.Enqueue(new TransactionOutPointWithValue(
                                         new OutPoint(b5.Transactions[0].GetHash(), 0),
                                         b5.Transactions[0].Outputs[0].Value,
                                         b5.Transactions[0].Outputs[0].ScriptPubKey));

            TransactionOutPointWithValue out3 = spendableOutputs.Dequeue();

            Block b6 = createNextBlock(b5, chainHeadHeight + 4, out3, null);

            blocks.Add(new BlockAndValidity(blockToHeightMap, hashHeaderMap, b6, true, false, b6.GetHash(), chainHeadHeight + 4, "b6"));


            //
            // genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3)
            // \-> b3 (1) -> b4 (2)
            //

            // Try to create a fork that double-spends
            // genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3)
            // \-> b7 (3) -> b8 (4)
            // \-> b3 (1) -> b4 (2)
            //
            Block b7 = createNextBlock(b5, chainHeadHeight + 4, out2, null);

            blocks.Add(new BlockAndValidity(blockToHeightMap, hashHeaderMap, b7, true, false, b6.GetHash(), chainHeadHeight + 4, "b7"));

            TransactionOutPointWithValue out4 = spendableOutputs.Dequeue();

            Block b8 = createNextBlock(b7, chainHeadHeight + 5, out4, null);

            blocks.Add(new BlockAndValidity(blockToHeightMap, hashHeaderMap, b8, false, true, b6.GetHash(), chainHeadHeight + 4, "b8"));

            return(ret);
        }
Ejemplo n.º 2
0
        internal RuleList GetBlocksToTest(bool addSigExpensiveBlocks, bool runLargeReorgs)
        {
            List<Rule> blocks = new List<Rule>();
            RuleList ret = new RuleList(blocks, hashHeaderMap, 10);

            Queue<TransactionOutPointWithValue> spendableOutputs = new Queue<TransactionOutPointWithValue>();

            int chainHeadHeight = 1;
            Block chainHead = Network.GetGenesis().CreateNextBlockWithCoinbase(coinbaseOutKeyPubKey, Money.Parse("50"));
            blocks.Add(new BlockAndValidity(blockToHeightMap, hashHeaderMap, chainHead, true, false, chainHead.GetHash(), 1, "Initial Block"));

            spendableOutputs.Enqueue(new TransactionOutPointWithValue(
                new OutPoint(chainHead.Transactions[0].GetHash(), 0),
                Money.Parse("50"), chainHead.Transactions[0].Outputs[0].ScriptPubKey));

            for(int i = 1 ; i < Network.SpendableCoinbaseDepth ; i++)
            {
                chainHead = chainHead.CreateNextBlockWithCoinbase(coinbaseOutKeyPubKey, Money.Parse("50"));
                chainHeadHeight++;
                blocks.Add(new BlockAndValidity(blockToHeightMap, hashHeaderMap, chainHead, true, false, chainHead.GetHash(), i + 1, "Initial Block chain output generation"));
                spendableOutputs.Enqueue(new TransactionOutPointWithValue(
                        new OutPoint(chainHead.Transactions[0].GetHash(), 0),
                        Money.Parse("50"), chainHead.Transactions.First().Outputs.First().ScriptPubKey));
            }

            // Start by building a couple of blocks on top of the genesis block.
            Block b1 = createNextBlock(chainHead, chainHeadHeight + 1, spendableOutputs.Dequeue(), null);
            blocks.Add(new BlockAndValidity(blockToHeightMap, hashHeaderMap, b1, true, false, b1.GetHash(), chainHeadHeight + 1, "b1"));
            spendableOutputs.Enqueue(new TransactionOutPointWithValue(
                    new OutPoint(b1.Transactions[0].GetHash(), 0),
                    b1.Transactions[0].Outputs[0].Value,
                    b1.Transactions[0].Outputs[0].ScriptPubKey));

            TransactionOutPointWithValue out1 = spendableOutputs.Dequeue();
            Assert.True(out1 != null);
            Block b2 = createNextBlock(b1, chainHeadHeight + 2, out1, null);
            blocks.Add(new BlockAndValidity(blockToHeightMap, hashHeaderMap, b2, true, false, b2.GetHash(), chainHeadHeight + 2, "b2"));
            // Make sure nothing funky happens if we try to re-add b2
            blocks.Add(new BlockAndValidity(blockToHeightMap, hashHeaderMap, b2, true, false, b2.GetHash(), chainHeadHeight + 2, "b2"));
            spendableOutputs.Enqueue(new TransactionOutPointWithValue(
                    new OutPoint(b2.Transactions[0].GetHash(), 0),
                    b2.Transactions[0].Outputs[0].Value,
                    b2.Transactions[0].Outputs[0].ScriptPubKey));
            // We now have the following chain (which output is spent is in parentheses):
            // genesis -> b1 (0) -> b2 (1)
            //
            // so fork like this:
            //
            // genesis -> b1 (0) -> b2 (1)
            // \-> b3 (1)
            //
            // Nothing should happen at this point. We saw b2 first so it takes priority.
            Block b3 = createNextBlock(b1, chainHeadHeight + 2, out1, null);
            blocks.Add(new BlockAndValidity(blockToHeightMap, hashHeaderMap, b3, true, false, b2.GetHash(), chainHeadHeight + 2, "b3"));
            // Make sure nothing breaks if we add b3 twice
            blocks.Add(new BlockAndValidity(blockToHeightMap, hashHeaderMap, b3, true, false, b2.GetHash(), chainHeadHeight + 2, "b3"));
            // Now we add another block to make the alternative chain longer.
            TransactionOutPointWithValue out2 = spendableOutputs.Dequeue();
            Assert.True(out2 != null);

            Block b4 = createNextBlock(b3, chainHeadHeight + 3, out2, null);
            blocks.Add(new BlockAndValidity(blockToHeightMap, hashHeaderMap, b4, true, false, b4.GetHash(), chainHeadHeight + 3, "b4"));

            //
            // genesis -> b1 (0) -> b2 (1)
            // \-> b3 (1) -> b4 (2)
            //
            // ... and back to the first chain.
            Block b5 = createNextBlock(b2, chainHeadHeight + 3, out2, null);
            blocks.Add(new BlockAndValidity(blockToHeightMap, hashHeaderMap, b5, true, false, b4.GetHash(), chainHeadHeight + 3, "b5"));
            spendableOutputs.Enqueue(new TransactionOutPointWithValue(
                    new OutPoint(b5.Transactions[0].GetHash(), 0),
                    b5.Transactions[0].Outputs[0].Value,
                    b5.Transactions[0].Outputs[0].ScriptPubKey));

            TransactionOutPointWithValue out3 = spendableOutputs.Dequeue();

            Block b6 = createNextBlock(b5, chainHeadHeight + 4, out3, null);
            blocks.Add(new BlockAndValidity(blockToHeightMap, hashHeaderMap, b6, true, false, b6.GetHash(), chainHeadHeight + 4, "b6"));

            //
            // genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3)
            // \-> b3 (1) -> b4 (2)
            //

            // Try to create a fork that double-spends
            // genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3)
            // \-> b7 (3) -> b8 (4)
            // \-> b3 (1) -> b4 (2)
            //
            Block b7 = createNextBlock(b5, chainHeadHeight + 4, out2, null);
            blocks.Add(new BlockAndValidity(blockToHeightMap, hashHeaderMap, b7, true, false, b6.GetHash(), chainHeadHeight + 4, "b7"));

            TransactionOutPointWithValue out4 = spendableOutputs.Dequeue();

            Block b8 = createNextBlock(b7, chainHeadHeight + 5, out4, null);
            blocks.Add(new BlockAndValidity(blockToHeightMap, hashHeaderMap, b8, false, true, b6.GetHash(), chainHeadHeight + 4, "b8"));

            return ret;
        }