public Testnet3Rules(Logger logger) : base(logger) { this._genesisBlock = new Block ( header: new BlockHeader ( version: 1, previousBlock: 0, merkleRoot: UInt256.Parse("4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b", NumberStyles.HexNumber), time: 1296688602, bits: 0x1D00FFFF, nonce: 414098458 ), transactions: ImmutableArray.Create ( new Transaction ( version: 1, inputs: ImmutableArray.Create ( new TxInput ( previousTxOutputKey: new TxOutputKey ( txHash: 0, txOutputIndex: 0xFFFFFFFF ), scriptSignature: ImmutableArray.Create <byte> ( 0x04, 0xFF, 0xFF, 0x00, 0x1D, 0x01, 0x04, 0x45, 0x54, 0x68, 0x65, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x73, 0x20, 0x30, 0x33, 0x2F, 0x4A, 0x61, 0x6E, 0x2F, 0x32, 0x30, 0x30, 0x39, 0x20, 0x43, 0x68, 0x61, 0x6E, 0x63, 0x65, 0x6C, 0x6C, 0x6F, 0x72, 0x20, 0x6F, 0x6E, 0x20, 0x62, 0x72, 0x69, 0x6E, 0x6B, 0x20, 0x6F, 0x66, 0x20, 0x73, 0x65, 0x63, 0x6F, 0x6E, 0x64, 0x20, 0x62, 0x61, 0x69, 0x6C, 0x6F, 0x75, 0x74, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x62, 0x61, 0x6E, 0x6B, 0x73 ), sequence: 0xFFFFFFFF ) ), outputs: ImmutableArray.Create ( new TxOutput ( value: (UInt64)(50L * 100.MILLION()), scriptPublicKey: ImmutableArray.Create <byte> ( 0x41, 0x04, 0x67, 0x8A, 0xFD, 0xB0, 0xFE, 0x55, 0x48, 0x27, 0x19, 0x67, 0xF1, 0xA6, 0x71, 0x30, 0xB7, 0x10, 0x5C, 0xD6, 0xA8, 0x28, 0xE0, 0x39, 0x09, 0xA6, 0x79, 0x62, 0xE0, 0xEA, 0x1F, 0x61, 0xDE, 0xB6, 0x49, 0xF6, 0xBC, 0x3F, 0x4C, 0xEF, 0x38, 0xC4, 0xF3, 0x55, 0x04, 0xE5, 0x1E, 0xC1, 0x12, 0xDE, 0x5C, 0x38, 0x4D, 0xF7, 0xBA, 0x0B, 0x8D, 0x57, 0x8A, 0x4C, 0x70, 0x2B, 0x6B, 0xF1, 0x1D, 0x5F, 0xAC ) ) ), lockTime: 0 ) ) ); Debug.Assert(_genesisBlock.Hash == UInt256.Parse("000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943", NumberStyles.HexNumber)); this._genesisChainedHeader = ChainedHeader.CreateForGenesisBlock(this._genesisBlock.Header); }
private void TestRollback(ITestStorageProvider provider) { var logger = LogManager.CreateNullLogger(); var sha256 = new SHA256Managed(); var blockProvider = new MainnetBlockProvider(); var blocks = Enumerable.Range(0, 500).Select(x => blockProvider.GetBlock(x)).ToList(); var genesisBlock = blocks[0]; var genesisHeader = new ChainedHeader(genesisBlock.Header, height: 0, totalWork: 0); var genesisChain = Chain.CreateForGenesisBlock(genesisHeader); var rules = new MainnetRules(logger); using (var storageManager = provider.OpenStorageManager()) using (var coreStorage = new CoreStorage(storageManager, logger)) using (var chainStateBuilder = new ChainStateBuilder(logger, rules, coreStorage)) { // add blocks to storage coreStorage.AddGenesisBlock(ChainedHeader.CreateForGenesisBlock(blocks[0].Header)); foreach (var block in blocks) { coreStorage.TryAddBlock(block); } // calculate utxo forward and store its state at each step along the way var expectedUtxos = new List <List <UnspentTx> >(); for (var blockIndex = 0; blockIndex < blocks.Count; blockIndex++) { var block = blocks[blockIndex]; var chainedHeader = new ChainedHeader(block.Header, blockIndex, 0); chainStateBuilder.AddBlock(chainedHeader, block.Transactions); using (var chainState = chainStateBuilder.ToImmutable()) { expectedUtxos.Add(chainState.ReadUnspentTransactions().ToList()); } } // verify the utxo state before rolling back //TODO verify the UTXO hash hard-coded here is correct var expectedUtxoHash = UInt256.Parse("609eb5882e0b71a707fb876c844fbfe6b4579e04eb27c7c0cefbb7478bac737b", NumberStyles.HexNumber); using (var utxoStream = new UtxoStream(logger, expectedUtxos.Last())) { var utxoHash = new UInt256(sha256.ComputeDoubleHash(utxoStream)); Assert.AreEqual(expectedUtxoHash, utxoHash); } expectedUtxos.RemoveAt(expectedUtxos.Count - 1); // roll utxo backwards and validate its state at each step along the way for (var blockIndex = blocks.Count - 1; blockIndex >= 1; blockIndex--) { var block = blocks[blockIndex]; var chainedHeader = new ChainedHeader(block.Header, blockIndex, 0); var blockTxes = block.Transactions.Select((tx, txIndex) => new BlockTx(txIndex, 0, tx.Hash, /*pruned:*/ false, tx)); chainStateBuilder.RollbackBlock(chainedHeader, blockTxes); var expectedUtxo = expectedUtxos.Last(); expectedUtxos.RemoveAt(expectedUtxos.Count - 1); List <UnspentTx> actualUtxo; using (var chainState = chainStateBuilder.ToImmutable()) { actualUtxo = chainState.ReadUnspentTransactions().ToList(); } CollectionAssert.AreEqual(expectedUtxo, actualUtxo, "UTXO differs at height: {0}".Format2(blockIndex)); } } }
public void SetGenesisBlock(Block genesisBlock) { this._genesisBlock = genesisBlock; this._genesisChainedHeader = ChainedHeader.CreateForGenesisBlock(this._genesisBlock.Header); }
public void TestSimpleChain() { // prepare test kernel var kernel = new StandardKernel(new ConsoleLoggingModule(), new MemoryStorageModule()); kernel.Bind <CoreStorage>().ToSelf().InSingletonScope(); var coreStorage = kernel.Get <CoreStorage>(); // initialize data var fakeHeaders = new FakeHeaders(); var header0 = fakeHeaders.Genesis(); var header1 = fakeHeaders.Next(); var header2 = fakeHeaders.Next(); // store genesis block var chainedHeader0 = ChainedHeader.CreateForGenesisBlock(header0); coreStorage.AddGenesisBlock(chainedHeader0); // mock rules var mockRules = new Mock <IBlockchainRules>(); mockRules.Setup(rules => rules.GenesisChainedHeader).Returns(chainedHeader0); kernel.Bind <IBlockchainRules>().ToConstant(mockRules.Object); // initialize the target chain worker using (var targetChainWorker = kernel.Get <TargetChainWorker>(new ConstructorArgument("workerConfig", new WorkerConfig(initialNotify: true, minIdleTime: TimeSpan.Zero, maxIdleTime: TimeSpan.MaxValue)))) { // verify initial state Assert.AreEqual(null, targetChainWorker.TargetChain); // monitor event firing var targetChainChangedEvent = new AutoResetEvent(false); var onTargetChainChangedCount = 0; targetChainWorker.OnTargetChainChanged += () => { onTargetChainChangedCount++; targetChainChangedEvent.Set(); }; // start worker and wait for initial chain targetChainWorker.Start(); targetChainChangedEvent.WaitOne(); // verify chained to block 0 Assert.AreEqual(chainedHeader0, targetChainWorker.TargetChain.LastBlock); AssertBlockListEquals(new[] { chainedHeader0 }, targetChainWorker.TargetChain.Blocks); Assert.AreEqual(1, onTargetChainChangedCount); // add block 1 ChainedHeader chainedHeader1; coreStorage.TryChainHeader(header1, out chainedHeader1); // wait for worker targetChainChangedEvent.WaitOne(); // verify chained to block 1 Assert.AreEqual(chainedHeader1, targetChainWorker.TargetChain.LastBlock); AssertBlockListEquals(new[] { chainedHeader0, chainedHeader1 }, targetChainWorker.TargetChain.Blocks); Assert.AreEqual(2, onTargetChainChangedCount); // add block 2 ChainedHeader chainedHeader2; coreStorage.TryChainHeader(header2, out chainedHeader2); // wait for worker targetChainChangedEvent.WaitOne(); // verify chained to block 2 Assert.AreEqual(chainedHeader2, targetChainWorker.TargetChain.LastBlock); AssertBlockListEquals(new[] { chainedHeader0, chainedHeader1, chainedHeader2 }, targetChainWorker.TargetChain.Blocks); Assert.AreEqual(3, onTargetChainChangedCount); // verify no other work was done Assert.IsFalse(targetChainChangedEvent.WaitOne(50)); } }
public void TestReverseChaining() { // prepare test kernel var kernel = new StandardKernel(new ConsoleLoggingModule(), new MemoryStorageModule(), new CoreCacheModule(), new RulesModule(RulesEnum.MainNet)); var blockHeaderCache = kernel.Get <BlockHeaderCache>(); var chainedHeaderCache = kernel.Get <ChainedHeaderCache>(); // mock rules var mockRules = Mock.Of <IBlockchainRules>(); // initialize data var blockHeader0 = new BlockHeader(version: 0, previousBlock: 0, merkleRoot: 0, time: 0, bits: 0x1D00FFFF, nonce: 0); var blockHeader1 = new BlockHeader(version: 0, previousBlock: blockHeader0.Hash, merkleRoot: 0, time: 0, bits: 0x1D00FFFF, nonce: 0); var blockHeader2 = new BlockHeader(version: 0, previousBlock: blockHeader1.Hash, merkleRoot: 0, time: 0, bits: 0x1D00FFFF, nonce: 0); var blockHeader3 = new BlockHeader(version: 0, previousBlock: blockHeader2.Hash, merkleRoot: 0, time: 0, bits: 0x1D00FFFF, nonce: 0); var blockHeader4 = new BlockHeader(version: 0, previousBlock: blockHeader3.Hash, merkleRoot: 0, time: 0, bits: 0x1D00FFFF, nonce: 0); // store genesis block blockHeaderCache[blockHeader0.Hash] = blockHeader0; chainedHeaderCache[blockHeader0.Hash] = ChainedHeader.CreateForGenesisBlock(blockHeader0); // initialize the chaining worker using (var chainingWorker = kernel.Get <ChainingWorker>(new ConstructorArgument("workerConfig", new WorkerConfig(initialNotify: false, minIdleTime: TimeSpan.Zero, maxIdleTime: TimeSpan.MaxValue)))) { // monitor event firing var workStoppedEvent = new AutoResetEvent(false); chainingWorker.OnWorkStopped += () => workStoppedEvent.Set(); // start and wait for initial chaining chainingWorker.Start(); workStoppedEvent.WaitOne(); // add block 4 blockHeaderCache[blockHeader4.Hash] = blockHeader4; // wait for chaining workStoppedEvent.WaitOne(); // verify nothing chained Assert.AreEqual(1, chainedHeaderCache.Count); Assert.AreEqual(1, chainingWorker.UnchainedByPrevious.Count); AssertSingleUnchainedHeaderByPrevious(blockHeader4, chainingWorker.UnchainedByPrevious); // add block 3 blockHeaderCache[blockHeader3.Hash] = blockHeader3; // wait for chaining workStoppedEvent.WaitOne(); // verify nothing chained Assert.AreEqual(1, chainedHeaderCache.Count); Assert.AreEqual(2, chainingWorker.UnchainedByPrevious.Count); AssertSingleUnchainedHeaderByPrevious(blockHeader3, chainingWorker.UnchainedByPrevious); AssertSingleUnchainedHeaderByPrevious(blockHeader4, chainingWorker.UnchainedByPrevious); // add block 2 blockHeaderCache[blockHeader2.Hash] = blockHeader2; // wait for chaining workStoppedEvent.WaitOne(); // verify nothing chained Assert.AreEqual(1, chainedHeaderCache.Count); Assert.AreEqual(3, chainingWorker.UnchainedByPrevious.Count); Assert.IsTrue(chainingWorker.UnchainedByPrevious.ContainsKey(blockHeader2.PreviousBlock)); AssertSingleUnchainedHeaderByPrevious(blockHeader2, chainingWorker.UnchainedByPrevious); AssertSingleUnchainedHeaderByPrevious(blockHeader3, chainingWorker.UnchainedByPrevious); AssertSingleUnchainedHeaderByPrevious(blockHeader4, chainingWorker.UnchainedByPrevious); // add block 1 blockHeaderCache[blockHeader1.Hash] = blockHeader1; // wait for chaining workStoppedEvent.WaitOne(); // verify all blocks chained Assert.AreEqual(5, chainedHeaderCache.Count); Assert.AreEqual(0, chainingWorker.UnchainedByPrevious.Count); // verify block 1 Assert.IsTrue(chainedHeaderCache.ContainsKey(blockHeader1.Hash)); Assert.AreEqual( new ChainedHeader( blockHeader: blockHeader1, height: 1, totalWork: new[] { blockHeader0, blockHeader1 }.SumBigInteger(x => x.CalculateWork()) ) , chainedHeaderCache[blockHeader1.Hash]); // verify block 2 Assert.IsTrue(chainedHeaderCache.ContainsKey(blockHeader2.Hash)); Assert.AreEqual( new ChainedHeader( blockHeader: blockHeader2, height: 2, totalWork: new[] { blockHeader0, blockHeader1, blockHeader2 }.SumBigInteger(x => x.CalculateWork()) ) , chainedHeaderCache[blockHeader2.Hash]); // verify block 3 Assert.IsTrue(chainedHeaderCache.ContainsKey(blockHeader3.Hash)); Assert.AreEqual( new ChainedHeader( blockHeader: blockHeader3, height: 3, totalWork: new[] { blockHeader0, blockHeader1, blockHeader2, blockHeader3 }.SumBigInteger(x => x.CalculateWork()) ) , chainedHeaderCache[blockHeader3.Hash]); // verify block 4 Assert.IsTrue(chainedHeaderCache.ContainsKey(blockHeader4.Hash)); Assert.AreEqual( new ChainedHeader( blockHeader: blockHeader4, height: 4, totalWork: new[] { blockHeader0, blockHeader1, blockHeader2, blockHeader3, blockHeader4 }.SumBigInteger(x => x.CalculateWork()) ) , chainedHeaderCache[blockHeader4.Hash]); // verify no other work was done Assert.IsFalse(workStoppedEvent.WaitOne(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)); } }
public MainnetParams() { GenesisChainedHeader = ChainedHeader.CreateForGenesisBlock(genesisBlock.Header); }
public MainnetRules(Logger logger) { this.logger = logger; this.highestTarget = UInt256.Parse("00000000FFFF0000000000000000000000000000000000000000000000000000", NumberStyles.HexNumber); this.genesisBlock = new Block ( header: new BlockHeader ( version: 1, previousBlock: 0, merkleRoot: UInt256.Parse("4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b", NumberStyles.HexNumber), time: 1231006505, bits: 0x1D00FFFF, nonce: 2083236893 ), transactions: ImmutableArray.Create ( new Transaction ( version: 1, inputs: ImmutableArray.Create ( new TxInput ( previousTxOutputKey: new TxOutputKey ( txHash: 0, txOutputIndex: 0xFFFFFFFF ), scriptSignature: ImmutableArray.Create <byte> ( 0x04, 0xFF, 0xFF, 0x00, 0x1D, 0x01, 0x04, 0x45, 0x54, 0x68, 0x65, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x73, 0x20, 0x30, 0x33, 0x2F, 0x4A, 0x61, 0x6E, 0x2F, 0x32, 0x30, 0x30, 0x39, 0x20, 0x43, 0x68, 0x61, 0x6E, 0x63, 0x65, 0x6C, 0x6C, 0x6F, 0x72, 0x20, 0x6F, 0x6E, 0x20, 0x62, 0x72, 0x69, 0x6E, 0x6B, 0x20, 0x6F, 0x66, 0x20, 0x73, 0x65, 0x63, 0x6F, 0x6E, 0x64, 0x20, 0x62, 0x61, 0x69, 0x6C, 0x6F, 0x75, 0x74, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x62, 0x61, 0x6E, 0x6B, 0x73 ), sequence: 0xFFFFFFFF ) ), outputs: ImmutableArray.Create ( new TxOutput ( value: 50 * SATOSHI_PER_BTC, scriptPublicKey: ImmutableArray.Create <byte> ( 0x41, 0x04, 0x67, 0x8A, 0xFD, 0xB0, 0xFE, 0x55, 0x48, 0x27, 0x19, 0x67, 0xF1, 0xA6, 0x71, 0x30, 0xB7, 0x10, 0x5C, 0xD6, 0xA8, 0x28, 0xE0, 0x39, 0x09, 0xA6, 0x79, 0x62, 0xE0, 0xEA, 0x1F, 0x61, 0xDE, 0xB6, 0x49, 0xF6, 0xBC, 0x3F, 0x4C, 0xEF, 0x38, 0xC4, 0xF3, 0x55, 0x04, 0xE5, 0x1E, 0xC1, 0x12, 0xDE, 0x5C, 0x38, 0x4D, 0xF7, 0xBA, 0x0B, 0x8D, 0x57, 0x8A, 0x4C, 0x70, 0x2B, 0x6B, 0xF1, 0x1D, 0x5F, 0xAC ) ) ), lockTime: 0 ) ) ); this.genesisChainedHeader = ChainedHeader.CreateForGenesisBlock(this.genesisBlock.Header); }
public void TestTargetChainReorganize() { // prepare test kernel var kernel = new StandardKernel(new ConsoleLoggingModule(), new MemoryStorageModule()); kernel.Bind <CoreStorage>().ToSelf().InSingletonScope(); var coreStorage = kernel.Get <CoreStorage>(); // initialize data var fakeHeaders = new FakeHeaders(); var header0 = fakeHeaders.Genesis(); var header1 = fakeHeaders.Next(); var header2 = fakeHeaders.Next(); var fakeHeadersA = new FakeHeaders(fakeHeaders); var header3A = fakeHeadersA.Next(); var header4A = fakeHeadersA.Next(); var header5A = fakeHeadersA.Next(); var fakeHeadersB = new FakeHeaders(fakeHeaders); var header3B = fakeHeadersB.Next(); var header4B = fakeHeadersB.Next(DataCalculator.ToCompact(UnitTestParams.Target2)); // store genesis block var chainedHeader0 = ChainedHeader.CreateForGenesisBlock(header0); coreStorage.AddGenesisBlock(chainedHeader0); // mock chain params var mockChainParams = new Mock <IChainParams>(); mockChainParams.Setup(rules => rules.GenesisChainedHeader).Returns(chainedHeader0); kernel.Bind <IChainParams>().ToConstant(mockChainParams.Object); // initialize the target chain worker using (var targetChainWorker = kernel.Get <TargetChainWorker>(new ConstructorArgument("workerConfig", new WorkerConfig(initialNotify: true, minIdleTime: TimeSpan.Zero, maxIdleTime: TimeSpan.MaxValue)))) { // monitor event firing var targetChainChangedEvent = new AutoResetEvent(false); var onTargetChainChangedCount = 0; targetChainWorker.OnTargetChainChanged += () => { onTargetChainChangedCount++; targetChainChangedEvent.Set(); }; // start worker and wait for initial chain targetChainWorker.Start(); targetChainChangedEvent.WaitOne(); // verify chained to block 0 Assert.AreEqual(chainedHeader0, targetChainWorker.TargetChain.LastBlock); AssertBlockListEquals(new[] { chainedHeader0 }, targetChainWorker.TargetChain.Blocks); Assert.AreEqual(1, onTargetChainChangedCount); // add block 1 ChainedHeader chainedHeader1; coreStorage.TryChainHeader(header1, out chainedHeader1); // wait for worker targetChainChangedEvent.WaitOne(); // verify chained to block 1 Assert.AreEqual(chainedHeader1, targetChainWorker.TargetChain.LastBlock); AssertBlockListEquals(new[] { chainedHeader0, chainedHeader1 }, targetChainWorker.TargetChain.Blocks); Assert.AreEqual(2, onTargetChainChangedCount); // add block 2 ChainedHeader chainedHeader2; coreStorage.TryChainHeader(header2, out chainedHeader2); // wait for worker targetChainChangedEvent.WaitOne(); // verify chained to block 2 Assert.AreEqual(chainedHeader2, targetChainWorker.TargetChain.LastBlock); AssertBlockListEquals(new[] { chainedHeader0, chainedHeader1, chainedHeader2 }, targetChainWorker.TargetChain.Blocks); Assert.AreEqual(3, onTargetChainChangedCount); // add block 3A ChainedHeader chainedHeader3A; coreStorage.TryChainHeader(header3A, out chainedHeader3A); // wait for worker targetChainChangedEvent.WaitOne(); // verify chained to block 3A Assert.AreEqual(chainedHeader3A, targetChainWorker.TargetChain.LastBlock); AssertBlockListEquals(new[] { chainedHeader0, chainedHeader1, chainedHeader2, chainedHeader3A }, targetChainWorker.TargetChain.Blocks); Assert.AreEqual(4, onTargetChainChangedCount); // add block 4A ChainedHeader chainedHeader4A; coreStorage.TryChainHeader(header4A, out chainedHeader4A); // wait for worker targetChainChangedEvent.WaitOne(); // verify chained to block 4A Assert.AreEqual(chainedHeader4A, targetChainWorker.TargetChain.LastBlock); AssertBlockListEquals(new[] { chainedHeader0, chainedHeader1, chainedHeader2, chainedHeader3A, chainedHeader4A }, targetChainWorker.TargetChain.Blocks); Assert.AreEqual(5, onTargetChainChangedCount); // add block 5A ChainedHeader chainedHeader5A; coreStorage.TryChainHeader(header5A, out chainedHeader5A); // wait for worker targetChainChangedEvent.WaitOne(); // verify chained to block 5A Assert.AreEqual(chainedHeader5A, targetChainWorker.TargetChain.LastBlock); AssertBlockListEquals(new[] { chainedHeader0, chainedHeader1, chainedHeader2, chainedHeader3A, chainedHeader4A, chainedHeader5A }, targetChainWorker.TargetChain.Blocks); Assert.AreEqual(6, onTargetChainChangedCount); // add block 3B ChainedHeader chainedHeader3B; coreStorage.TryChainHeader(header3B, out chainedHeader3B); // wait for worker, it should not fire Assert.IsFalse(targetChainChangedEvent.WaitOne(50)); // verify no chaining done Assert.AreEqual(chainedHeader5A, targetChainWorker.TargetChain.LastBlock); AssertBlockListEquals(new[] { chainedHeader0, chainedHeader1, chainedHeader2, chainedHeader3A, chainedHeader4A, chainedHeader5A }, targetChainWorker.TargetChain.Blocks); Assert.AreEqual(6, onTargetChainChangedCount); // add block 4B ChainedHeader chainedHeader4B; coreStorage.TryChainHeader(header4B, out chainedHeader4B); // wait for worker targetChainChangedEvent.WaitOne(); // verify chained to block 4B Assert.AreEqual(chainedHeader4B, targetChainWorker.TargetChain.LastBlock); AssertBlockListEquals(new[] { chainedHeader0, chainedHeader1, chainedHeader2, chainedHeader3B, chainedHeader4B }, targetChainWorker.TargetChain.Blocks); Assert.AreEqual(7, onTargetChainChangedCount); // verify no other work was done Assert.IsFalse(targetChainChangedEvent.WaitOne(50)); } }
public Testnet2Rules(Logger logger, BlockHeaderCache blockHeaderCache) : base(logger, blockHeaderCache) { this._genesisBlock = new Block ( header: new BlockHeader ( version: 1, previousBlock: 0, merkleRoot: UInt256.Parse("4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b", NumberStyles.HexNumber), time: 1296688602, bits: 0x207FFFFF, nonce: 2 ), transactions: ImmutableArray.Create ( new Transaction ( version: 1, inputs: ImmutableArray.Create ( new TxInput ( previousTxOutputKey: new TxOutputKey ( txHash: 0, txOutputIndex: 0xFFFFFFFF ), scriptSignature: ImmutableArray.Create <byte> ( 0x04, 0xFF, 0xFF, 0x00, 0x1D, 0x01, 0x04, 0x45, 0x54, 0x68, 0x65, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x73, 0x20, 0x30, 0x33, 0x2F, 0x4A, 0x61, 0x6E, 0x2F, 0x32, 0x30, 0x30, 0x39, 0x20, 0x43, 0x68, 0x61, 0x6E, 0x63, 0x65, 0x6C, 0x6C, 0x6F, 0x72, 0x20, 0x6F, 0x6E, 0x20, 0x62, 0x72, 0x69, 0x6E, 0x6B, 0x20, 0x6F, 0x66, 0x20, 0x73, 0x65, 0x63, 0x6F, 0x6E, 0x64, 0x20, 0x62, 0x61, 0x69, 0x6C, 0x6F, 0x75, 0x74, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x62, 0x61, 0x6E, 0x6B, 0x73 ), sequence: 0xFFFFFFFF ) ), outputs: ImmutableArray.Create ( new TxOutput ( value: (UInt64)(50L * 100.MILLION()), scriptPublicKey: ImmutableArray.Create <byte> ( 0x41, 0x04, 0x67, 0x8A, 0xFD, 0xB0, 0xFE, 0x55, 0x48, 0x27, 0x19, 0x67, 0xF1, 0xA6, 0x71, 0x30, 0xB7, 0x10, 0x5C, 0xD6, 0xA8, 0x28, 0xE0, 0x39, 0x09, 0xA6, 0x79, 0x62, 0xE0, 0xEA, 0x1F, 0x61, 0xDE, 0xB6, 0x49, 0xF6, 0xBC, 0x3F, 0x4C, 0xEF, 0x38, 0xC4, 0xF3, 0x55, 0x04, 0xE5, 0x1E, 0xC1, 0x12, 0xDE, 0x5C, 0x38, 0x4D, 0xF7, 0xBA, 0x0B, 0x8D, 0x57, 0x8A, 0x4C, 0x70, 0x2B, 0x6B, 0xF1, 0x1D, 0x5F, 0xAC ) ) ), lockTime: 0 ) ) ); Debug.Assert(_genesisBlock.Hash == UInt256.Parse("0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206", NumberStyles.HexNumber)); this._genesisChainedHeader = ChainedHeader.CreateForGenesisBlock(this._genesisBlock.Header); }
public void SetGenesisBlock(Block genesisBlock) { GenesisBlock = genesisBlock; GenesisChainedHeader = ChainedHeader.CreateForGenesisBlock(genesisBlock.Header); }
public Testnet3Params() { GenesisChainedHeader = ChainedHeader.CreateForGenesisBlock(genesisBlock.Header); }