public async Task SendBlock(Block block) { await Task.Yield(); var sendBlockMessage = Messaging.ConstructMessage("block", DataEncoder.EncodeBlock(block)); await SendMessageAsync(sendBlockMessage); }
public static byte[] EncodeBlock(Block block) { using (var stream = new MemoryStream()) using (var writer = new BinaryWriter(stream)) { EncodeBlock(writer, block); return stream.ToArray(); } }
public TestDaemon(Block genesisBlock = null, INinjectModule loggingModule = null, INinjectModule[] storageModules = null) { // initialize storage folder this.baseDirectoryCleanup = TempDirectory.CreateTempDirectory(out this.baseDirectory); // initialize kernel this.kernel = new StandardKernel(); // add logging module this.kernel.Load(loggingModule ?? new ConsoleLoggingModule()); // log startup this.logger = LogManager.GetCurrentClassLogger(); this.logger.Info($"Starting up: {DateTime.Now}"); // initialize test blocks this.testBlocks = new TestBlocks(genesisBlock); // add storage module this.kernel.Load(storageModules ?? new[] { new MemoryStorageModule() }); // initialize unit test rules, allow validation methods to run testBlocks.Rules.ValidateTransactionAction = null; testBlocks.Rules.ValidationTransactionScriptAction = null; this.kernel.Bind<ChainType>().ToConstant(ChainType.Regtest); this.kernel.Bind<ICoreRules>().ToConstant(testBlocks.Rules); this.kernel.Bind<IChainParams>().ToConstant(testBlocks.ChainParams); // by default, don't run scripts in unit tests testBlocks.Rules.IgnoreScripts = true; // initialize the blockchain daemon this.kernel.Bind<CoreDaemon>().ToSelf().InSingletonScope(); this.coreDaemon = this.kernel.Get<CoreDaemon>(); try { this.coreStorage = this.coreDaemon.CoreStorage; // start the blockchain daemon this.coreDaemon.Start(); // wait for initial work this.coreDaemon.WaitForUpdate(); // verify initial state Assert.AreEqual(0, this.coreDaemon.TargetChainHeight); Assert.AreEqual(testBlocks.ChainParams.GenesisBlock.Hash, this.coreDaemon.TargetChain.LastBlock.Hash); Assert.AreEqual(testBlocks.ChainParams.GenesisBlock.Hash, this.coreDaemon.CurrentChain.LastBlock.Hash); } catch (Exception) { this.coreDaemon.Dispose(); throw; } }
public static IntegrationTestDaemon Create(Block genesisBlock = null) { var baseDirectory = TempDirectory.CreateTempDirectory(); var loggingModule = new LoggingModule(baseDirectory, LogLevel.Info); var storageModules = new[] { new EsentStorageModule(baseDirectory, ChainType.Regtest, cacheSizeMaxBytes: 500.MILLION()) }; return new IntegrationTestDaemon(genesisBlock, baseDirectory, loggingModule, storageModules); }
public static IntegrationTestDaemon Create(Block genesisBlock = null, bool useLmdb = false) { var baseDirectory = TempDirectory.CreateTempDirectory(); var loggingModule = new LoggingModule(baseDirectory, LogLevel.Info); var storageModules = useLmdb ? new INinjectModule[] { new EsentStorageModule(baseDirectory, RulesEnum.TestNet2, blockStorage: !useLmdb, cacheSizeMaxBytes: 500.MILLION()), new LmdbStorageModule(baseDirectory, RulesEnum.TestNet2) } : new[] { new EsentStorageModule(baseDirectory, RulesEnum.TestNet2, cacheSizeMaxBytes: 500.MILLION()) }; return new IntegrationTestDaemon(genesisBlock, baseDirectory, loggingModule, storageModules); }
public TestBlocks(Block genesisBlock = null) { // create the key pair that block rewards will be sent to var keyPair = txManager.CreateKeyPair(); coinbasePrivateKey = keyPair.Item1; coinbasePublicKey = keyPair.Item2; // create and mine the genesis block genesisBlock = genesisBlock ?? MineEmptyBlock(UInt256.Zero); // initialize unit test rules rules = new UnitTestRules() { // disable execution of rules validation ValidateTransactionAction = (_, __) => { }, ValidationTransactionScriptAction = (_, __, ___, ____, _____) => { } }; ChainParams.SetGenesisBlock(genesisBlock); blocks.Add(genesisBlock); chain.AddBlock(ChainParams.GenesisChainedHeader); }
public Block MineAndAddBlock(Block newBlock) { var block = MineBlock(newBlock); AddBlock(block); return block; }
public Block MineBlock(Block block) { var minedHeader = this.miner.MineBlockHeader(block.Header, DataCalculator.BitsToTarget(block.Header.Bits)); if (minedHeader == null) Assert.Fail("No block could be mined for test data header."); block = block.With(Header: minedHeader); return block; }
public void AddBlock(Block block) { this.coreStorage.TryAddBlock(block); }
//TODO copy pasted private Block CreateFakeBlock(int txCount) { var transactions = Enumerable.Range(0, txCount).Select(x => RandomData.RandomTransaction()).ToImmutableArray(); var blockHeader = RandomData.RandomBlockHeader().With(MerkleRoot: MerkleTree.CalculateMerkleRoot(transactions), Bits: DataCalculator.TargetToBits(UnitTestRules.Target0)); var block = new Block(blockHeader, transactions); return block; }
public ChainedBlock(ChainedHeader chainedHeader, Block block) { ChainedHeader = chainedHeader; Block = block; }
private IntegrationTestDaemon(Block genesisBlock, string baseDirectory, INinjectModule loggingModule, INinjectModule[] storageModules) : base(genesisBlock, loggingModule, storageModules) { this.baseDirectory = baseDirectory; }
public static void EncodeBlock(BinaryWriter writer, Block block) { EncodeBlockHeader(writer, block.Header); writer.WriteList(block.BlockTxes, tx => writer.WriteBytes(tx.TxBytes.ToArray())); }
public void SetGenesisBlock(Block genesisBlock) { GenesisBlock = genesisBlock; GenesisChainedHeader = ChainedHeader.CreateForGenesisBlock(genesisBlock.Header); }
public Block MineAndAddBlock(Block newBlock) { var block = testBlocks.MineAndAddBlock(newBlock); AddBlock(block); return block; }
public static void EncodeBlock(BinaryWriter writer, Block block) { EncodeBlockHeader(writer, block.Header); writer.WriteList(block.Transactions, tx => EncodeTransaction(writer, tx)); }
public static void GetTransaction(MainnetBlockProvider blockProvider, int blockIndex, int txIndex, out Block block, out Transaction tx) { block = blockProvider.GetBlock(blockIndex); tx = block.Transactions[txIndex]; }
public static void GetFirstHash160Transaction(MainnetBlockProvider blockProvider, out Block block, out Transaction tx, out IDictionary<UInt256, Transaction> txLookup) { txLookup = new Dictionary<UInt256, Transaction>(); // prior outputs for first OP_HASH160 transaction GetTransaction(blockProvider, 2676, 0, out block, out tx); txLookup.Add(tx.Hash, tx); GetTransaction(blockProvider, 2812, 1, out block, out tx); txLookup.Add(tx.Hash, tx); // first OP_HASH160 transaction // do this last so its output is what is returned GetTransaction(blockProvider, 2812, 2, out block, out tx); txLookup.Add(tx.Hash, tx); }
public static void GetFirstMultiInputTransaction(MainnetBlockProvider blockProvider, out Block block, out Transaction tx, out IDictionary<UInt256, Transaction> txLookup) { txLookup = new Dictionary<UInt256, Transaction>(); // prior outputs for first transaction GetTransaction(blockProvider, 360, 0, out block, out tx); txLookup.Add(tx.Hash, tx); GetTransaction(blockProvider, 187, 1, out block, out tx); txLookup.Add(tx.Hash, tx); GetTransaction(blockProvider, 248, 1, out block, out tx); txLookup.Add(tx.Hash, tx); // first transaction // do this last so its output is what is returned GetTransaction(blockProvider, 496, 1, out block, out tx); txLookup.Add(tx.Hash, tx); }
public void SetGenesisBlock(Block genesisBlock) { this._genesisBlock = genesisBlock; this._genesisChainedHeader = ChainedHeader.CreateForGenesisBlock(this._genesisBlock.Header); }
public void AddBlock(Block block) { blocks.Add(block); chain.AddBlock(ChainedHeader.CreateFromPrev(chain.LastBlock, block.Header, DateTimeOffset.Now)); Debug.Assert(chain.Height == blocks.Count - 1); }
public Block CreateBlock(UInt256 previousBlockHash, int txCount, UInt256 target = null) { var coinbaseTx = new Transaction ( version: 0, inputs: ImmutableArray.Create ( new TxInput ( previousTxOutputKey: new TxOutputKey ( txHash: UInt256.Zero, txOutputIndex: 0 ), scriptSignature: previousBlockHash.ToByteArray().Concat(random.NextBytes(100)).ToImmutableArray(), sequence: 0 ) ), outputs: ImmutableArray.Create ( new TxOutput ( value: 50 * SATOSHI_PER_BTC, scriptPublicKey: this.txManager.CreatePublicKeyScript(coinbasePublicKey).ToImmutableArray() ) ), lockTime: 0 ); var transactionsBuilder = ImmutableArray.CreateBuilder<Transaction>(txCount + 1); transactionsBuilder.Add(coinbaseTx); var prevTx = coinbaseTx; for (var i = 1; i < transactionsBuilder.Capacity; i++) { var outputs = i % 2 == 0 ? ImmutableArray.Create( new TxOutput(prevTx.Outputs[0].Value - 1, coinbaseTx.Outputs[0].ScriptPublicKey), new TxOutput(1, coinbaseTx.Outputs[0].ScriptPublicKey)) : ImmutableArray.Create(new TxOutput(prevTx.Outputs[0].Value - 1, coinbaseTx.Outputs[0].ScriptPublicKey)); var tx = new Transaction( version: 0, inputs: ImmutableArray.Create(new TxInput(new TxOutputKey(prevTx.Hash, 0), new byte[100].ToImmutableArray(), 0)), outputs: outputs, lockTime: 0); transactionsBuilder.Add(tx); prevTx = tx; } var transactions = transactionsBuilder.MoveToImmutable(); var merkleRoot = MerkleTree.CalculateMerkleRoot(transactions); var block = new Block ( header: new BlockHeader ( version: 0, previousBlock: previousBlockHash, merkleRoot: merkleRoot, time: 0, bits: DataCalculator.TargetToBits(target ?? UnitTestRules.Target0), nonce: 0 ), transactions: transactions ); return block; }
public bool TryAddBlock(Block block) { if (this.ContainsBlockTxes(block.Hash)) return false; lock (GetBlockLock(block.Hash)) { ChainedHeader chainedHeader; if (TryGetChainedHeader(block.Hash, out chainedHeader) || TryChainHeader(block.Header, out chainedHeader)) { if (this.blockTxesStorage.Value.TryAddBlockTransactions(block.Hash, block.BlockTxes)) { this.presentBlockTxes[block.Hash] = true; BlockTxesAdded?.Invoke(chainedHeader); return true; } } return false; }; }
public bool TryGetBlock(UInt256 blockHash, out Block block) { ChainedHeader chainedHeader; if (!TryGetChainedHeader(blockHash, out chainedHeader)) { block = default(Block); return false; } IEnumerator<BlockTx> blockTxes; if (TryReadBlockTransactions(chainedHeader.Hash, /*requireTransactions:*/true, out blockTxes)) { var transactions = ImmutableArray.CreateRange(blockTxes.UsingAsEnumerable().Select(x => x.Transaction)); block = new Block(chainedHeader.BlockHeader, transactions); return true; } else { block = default(Block); return false; } }
public bool TryGetBlock(UInt256 blockHash, out Block block) { ChainedHeader chainedHeader; if (!TryGetChainedHeader(blockHash, out chainedHeader)) { block = default(Block); return false; } IEnumerator<BlockTx> blockTxes; if (TryReadBlockTransactions(chainedHeader.Hash, out blockTxes)) { block = new Block(chainedHeader.BlockHeader, blockTxes.UsingAsEnumerable().ToImmutableArray()); return true; } else { block = default(Block); return false; } }
public Block AddBlock(Block block) { if (!this.coreStorage.TryAddBlock(block)) Assert.Fail($"Failed to store block: {block.Hash}"); return block; }
public MainnetRules() { this.highestTarget = UInt256.ParseHex("00000000FFFF0000000000000000000000000000000000000000000000000000"); this.genesisBlock = new Block ( header: new BlockHeader ( version: 1, previousBlock: UInt256.Zero, merkleRoot: UInt256.ParseHex("4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"), time: 1231006505, bits: 0x1D00FFFF, nonce: 2083236893 ), transactions: ImmutableArray.Create ( new Transaction ( version: 1, inputs: ImmutableArray.Create ( new TxInput ( previousTxOutputKey: new TxOutputKey ( txHash: UInt256.Zero, 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 Testnet2Rules() { this._genesisBlock = new Block ( header: new BlockHeader ( version: 1, previousBlock: UInt256.Zero, merkleRoot: UInt256.ParseHex("4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"), time: 1296688602, bits: 0x207FFFFF, nonce: 2 ), transactions: ImmutableArray.Create ( new Transaction ( version: 1, inputs: ImmutableArray.Create ( new TxInput ( previousTxOutputKey: new TxOutputKey ( txHash: UInt256.Zero, 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.ParseHex("0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206")); this._genesisChainedHeader = ChainedHeader.CreateForGenesisBlock(this._genesisBlock.Header); }
public Block MineAndAddBlock(Block newBlock, UInt256 target = null) { var block = MineBlock(newBlock); AddBlock(block); return block; }