Beispiel #1
0
        public void TestCalculateTransactionHash()
        {
            var expectedHash = UInt256.ParseHex("4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b");
            var tx           = Transaction.Create
                               (
                version: 1,
                inputs: ImmutableArray.Create(
                    new TxInput
                    (
                        prevTxHash: UInt256.Zero,
                        prevTxOutputIndex: 4294967295,
                        scriptSignature: "04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73".HexToByteArray().ToImmutableArray(),
                        sequence: 4294967295
                    )),
                outputs: ImmutableArray.Create(
                    new TxOutput
                    (
                        value: (UInt64)(50L * 100.MILLION()),
                        scriptPublicKey: "4104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac".HexToByteArray().ToImmutableArray()
                    )),
                lockTime: 0
                               ).Transaction;

            Assert.AreEqual(expectedHash, tx.Hash);
        }
Beispiel #2
0
        public void TestToCompact()
        {
            var target1   = UInt256.ParseHex("404cb000000000000000000000000000000000000000000000000");
            var expected1 = 0x1b0404cbU;
            var actual1   = DataCalculator.ToCompact(target1);

            Assert.AreEqual(expected1, actual1);

            // difficulty: 1
            var target2   = UInt256.ParseHex("ffff0000000000000000000000000000000000000000000000000000");
            var expected2 = 0x1d00ffffU;
            var actual2   = DataCalculator.ToCompact(target2);

            Assert.AreEqual(expected2, actual2);

            var target3   = UInt256.ParseHex("7fff0000000000000000000000000000000000000000000000000000");
            var expected3 = 0x1c7fff00U;
            var actual3   = DataCalculator.ToCompact(target3);

            Assert.AreEqual(expected3, actual3);

            var target4   = UInt256.ParseHex("000000000000000000000000000000000000000000000000000404cb");
            var expected4 = 0x030404cbU;
            var actual4   = DataCalculator.ToCompact(target4);

            Assert.AreEqual(expected4, actual4);
        }
Beispiel #3
0
        public void TestUInt256Sha256()
        {
            var expected = SHA256Static.ComputeDoubleHash(UInt256.ParseHex(TestData.HEX_STRING_64).ToByteArray());
            var actual   = new UInt256(expected).ToByteArray();

            CollectionAssert.AreEqual(expected, actual);
        }
Beispiel #4
0
        public void TestUInt256Inequality()
        {
            var expected = UInt256.ParseHex(TestData.HEX_STRING_64);
            var actual   = UInt256.Zero;

            Assert.AreNotEqual(expected, actual);
            Assert.IsFalse(expected == actual);
            Assert.IsTrue(expected != actual);
            CollectionAssert.AreNotEqual(expected.ToByteArray(), actual.ToByteArray());
        }
Beispiel #5
0
        public void TestUInt256RawBytes()
        {
            var expected = UInt256.ParseHex(TestData.HEX_STRING_64);
            var actual1  = new UInt256(expected.ToByteArray());
            var actual2  = new UInt256(new UInt256(expected.ToByteArray()).ToByteArray());
            var actual3  = new UInt256(new UInt256(new UInt256(expected.ToByteArray()).ToByteArray()).ToByteArray());

            Assert.AreEqual(expected, actual1);
            Assert.AreEqual(expected, actual2);
            Assert.AreEqual(expected, actual3);
        }
Beispiel #6
0
        public void TestUInt256HexString()
        {
            var hex       = TestData.HEX_STRING_64;
            var expected1 = "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b";
            var expected2 = "[3b,a3,ed,fd,7a,7b,12,b2,7a,c7,2c,3e,67,76,8f,61,7f,c8,1b,c3,88,8a,51,32,3a,9f,b8,aa,4b,1e,5e,4a]";

            var actual1 = UInt256.ParseHex(hex).ToHexNumberString();
            var actual2 = UInt256.ParseHex(hex).ToHexDataString();

            Assert.AreEqual(expected1, actual1);
            Assert.AreEqual(expected2, actual2);
        }
Beispiel #7
0
        public void TestCalculateBlockHash()
        {
            var expectedHash = UInt256.ParseHex("000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f");
            var blockHeader  = BlockHeader.Create
                               (
                version: 1,
                previousBlock: UInt256.Zero,
                merkleRoot: UInt256.ParseHex("4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"),
                time: DateTimeOffset.FromUnixTimeSeconds(1231006505),
                bits: 0x1D00FFFF,
                nonce: 2083236893
                               );

            Assert.AreEqual(expectedHash, DataCalculator.CalculateBlockHash(blockHeader));
            Assert.AreEqual(expectedHash, DataCalculator.CalculateBlockHash(blockHeader.Version, blockHeader.PreviousBlock, blockHeader.MerkleRoot, blockHeader.Time, blockHeader.Bits, blockHeader.Nonce));
        }
Beispiel #8
0
        public void TestFromCompact()
        {
            var bits1     = 0x1b0404cbU;
            var expected1 = UInt256.ParseHex("404cb000000000000000000000000000000000000000000000000");
            var actual1   = DataCalculator.FromCompact(bits1);

            Assert.AreEqual(expected1, actual1);

            // difficulty: 1
            var bits2     = 0x1d00ffffU;
            var expected2 = UInt256.ParseHex("ffff0000000000000000000000000000000000000000000000000000");
            var actual2   = DataCalculator.FromCompact(bits2);

            Assert.AreEqual(expected2, actual2);

            var bits3     = 0x030404cbU;
            var expected3 = UInt256.ParseHex("000000000000000000000000000000000000000000000000404cb");
            var actual3   = DataCalculator.FromCompact(bits3);

            Assert.AreEqual(expected3, actual3);
        }
Beispiel #9
0
        public BlockProvider(string resourceName)
        {
            this.blocks      = new ConcurrentDictionary <string, Block>();
            this.heightNames = new Dictionary <int, string>();
            this.hashNames   = new Dictionary <UInt256, string>();

            var assembly = Assembly.GetCallingAssembly();
            var stream   = assembly.GetManifestResourceStream(resourceName);

            this.zip = new ZipArchive(stream);

            foreach (var entry in zip.Entries)
            {
                var chunks      = Path.GetFileNameWithoutExtension(entry.Name).Split('_');
                var blockHeight = int.Parse(chunks[0]);
                var blockHash   = UInt256.ParseHex(chunks[1]);

                heightNames.Add(blockHeight, entry.Name);
                hashNames.Add(blockHash, entry.Name);
            }
        }
Beispiel #10
0
        private void TestRollback(ITestStorageProvider provider)
        {
            ConsoleLoggingModule.Configure();
            var logger = LogManager.GetCurrentClassLogger();

            var blockCount = 10.THOUSAND();
            var checkUtxoHashFrequencey = 1000;

            var blockProvider = new TestNet3BlockProvider();
            var blocks        = blockProvider.ReadBlocks().Take(blockCount).ToList();

            var genesisBlock  = blocks[0];
            var genesisHeader = new ChainedHeader(genesisBlock.Header, height: 0, totalWork: 0, dateSeen: DateTimeOffset.Now);
            var genesisChain  = Chain.CreateForGenesisBlock(genesisHeader);

            var chainParams = new Testnet3Params();
            var rules       = new CoreRules(chainParams)
            {
                IgnoreScripts      = true,
                IgnoreSignatures   = true,
                IgnoreScriptErrors = true
            };

            using (var storageManager = provider.OpenStorageManager())
                using (var coreStorage = new CoreStorage(storageManager))
                    using (var chainStateBuilder = new ChainStateBuilder(rules, coreStorage, storageManager))
                    {
                        // add blocks to storage
                        coreStorage.AddGenesisBlock(ChainedHeader.CreateForGenesisBlock(blocks[0].Header));
                        foreach (var block in blocks)
                        {
                            coreStorage.TryAddBlock(block);
                        }

                        // store empty utxo hash
                        var expectedUtxoHashes = new List <UInt256>();
                        using (var chainState = chainStateBuilder.ToImmutable())
                            expectedUtxoHashes.Add(UtxoCommitment.ComputeHash(chainState));

                        // calculate utxo forward and store its state at each step along the way
                        for (var blockIndex = 0; blockIndex < blocks.Count; blockIndex++)
                        {
                            logger.Info($"Adding: {blockIndex:N0}");

                            var block         = blocks[blockIndex];
                            var chainedHeader = new ChainedHeader(block.Header, blockIndex, 0, DateTimeOffset.Now);

                            chainStateBuilder.AddBlockAsync(chainedHeader, block.Transactions.Select(
                                                                (tx, txIndex) => BlockTx.Create(txIndex, tx))).Wait();

                            if (blockIndex % checkUtxoHashFrequencey == 0 || blockIndex == blocks.Count - 1)
                            {
                                using (var chainState = chainStateBuilder.ToImmutable())
                                    expectedUtxoHashes.Add(UtxoCommitment.ComputeHash(chainState));
                            }
                        }

                        // verify the utxo state before rolling back
                        var expectedLastUtxoHash = UInt256.ParseHex("5f155c7d8a5c850d5fb2566aec5110caa40e270184126d17022ae9780fd65fd9");
                        Assert.AreEqual(expectedLastUtxoHash, expectedUtxoHashes.Last());
                        expectedUtxoHashes.RemoveAt(expectedUtxoHashes.Count - 1);

                        // roll utxo backwards and validate its state at each step along the way
                        for (var blockIndex = blocks.Count - 1; blockIndex >= 0; blockIndex--)
                        {
                            logger.Info($"Rolling back: {blockIndex:N0}");

                            var block         = blocks[blockIndex];
                            var chainedHeader = new ChainedHeader(block.Header, blockIndex, 0, DateTimeOffset.Now);
                            var blockTxes     = block.Transactions.Select((tx, txIndex) => BlockTx.Create(txIndex, tx));

                            chainStateBuilder.RollbackBlock(chainedHeader, blockTxes);

                            if ((blockIndex - 1) % checkUtxoHashFrequencey == 0 || blockIndex == 0)
                            {
                                var expectedUtxoHash = expectedUtxoHashes.Last();
                                expectedUtxoHashes.RemoveAt(expectedUtxoHashes.Count - 1);

                                using (var chainState = chainStateBuilder.ToImmutable())
                                    Assert.AreEqual(expectedUtxoHash, UtxoCommitment.ComputeHash(chainState));
                            }
                        }

                        // verify chain state was rolled all the way back
                        Assert.AreEqual(-1, chainStateBuilder.Chain.Height);
                        Assert.AreEqual(0, expectedUtxoHashes.Count);

                        // calculate utxo forward again
                        for (var blockIndex = 0; blockIndex < blocks.Count; blockIndex++)
                        {
                            logger.Info($"Adding: {blockIndex:N0}");

                            var block         = blocks[blockIndex];
                            var chainedHeader = new ChainedHeader(block.Header, blockIndex, 0, DateTimeOffset.Now);

                            chainStateBuilder.AddBlockAsync(chainedHeader, block.Transactions.Select(
                                                                (tx, txIndex) => BlockTx.Create(txIndex, tx))).Wait();
                        }

                        // verify final utxo state again
                        using (var chainState = chainStateBuilder.ToImmutable())
                            Assert.AreEqual(expectedLastUtxoHash, UtxoCommitment.ComputeHash(chainState));
                    }
        }