Esempio n. 1
0
        public async Task SendBlock(Block block)
        {
            await Task.Yield();

            var sendBlockMessage = Messaging.ConstructMessage("block", DataEncoder.EncodeBlock(block));

            await SendMessageAsync(sendBlockMessage);
        }
Esempio n. 2
0
 public static byte[] EncodeBlock(Block block)
 {
     using (var stream = new MemoryStream())
     using (var writer = new BinaryWriter(stream))
     {
         EncodeBlock(writer, block);
         return stream.ToArray();
     }
 }
Esempio n. 3
0
        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;
            }
        }
Esempio n. 4
0
        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);
        }
Esempio n. 6
0
        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);
        }
Esempio n. 7
0
 public Block MineAndAddBlock(Block newBlock)
 {
     var block = MineBlock(newBlock);
     AddBlock(block);
     return block;
 }
Esempio n. 8
0
        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;
        }
Esempio n. 9
0
 public void AddBlock(Block block)
 {
     this.coreStorage.TryAddBlock(block);
 }
Esempio n. 10
0
        //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;
        }
Esempio n. 11
0
 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;
 }
Esempio n. 13
0
 public static void EncodeBlock(BinaryWriter writer, Block block)
 {
     EncodeBlockHeader(writer, block.Header);
     writer.WriteList(block.BlockTxes, tx => writer.WriteBytes(tx.TxBytes.ToArray()));
 }
Esempio n. 14
0
 public void SetGenesisBlock(Block genesisBlock)
 {
     GenesisBlock = genesisBlock;
     GenesisChainedHeader = ChainedHeader.CreateForGenesisBlock(genesisBlock.Header);
 }
Esempio n. 15
0
 public Block MineAndAddBlock(Block newBlock)
 {
     var block = testBlocks.MineAndAddBlock(newBlock);
     AddBlock(block);
     return block;
 }
Esempio n. 16
0
 public static void EncodeBlock(BinaryWriter writer, Block block)
 {
     EncodeBlockHeader(writer, block.Header);
     writer.WriteList(block.Transactions, tx => EncodeTransaction(writer, tx));
 }
Esempio n. 17
0
 public static void GetTransaction(MainnetBlockProvider blockProvider, int blockIndex, int txIndex, out Block block, out Transaction tx)
 {
     block = blockProvider.GetBlock(blockIndex);
     tx = block.Transactions[txIndex];
 }
Esempio n. 18
0
        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);
        }
Esempio n. 19
0
        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);
        }
Esempio n. 20
0
 public void SetGenesisBlock(Block genesisBlock)
 {
     this._genesisBlock = genesisBlock;
     this._genesisChainedHeader = ChainedHeader.CreateForGenesisBlock(this._genesisBlock.Header);
 }
Esempio n. 21
0
        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);
        }
Esempio n. 22
0
        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;
        }
Esempio n. 23
0
        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;
            };
        }
Esempio n. 24
0
        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;
            }
        }
Esempio n. 25
0
        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;
            }
        }
Esempio n. 26
0
        public Block AddBlock(Block block)
        {
            if (!this.coreStorage.TryAddBlock(block))
                Assert.Fail($"Failed to store block: {block.Hash}");

            return block;
        }
Esempio n. 27
0
        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);
        }
Esempio n. 28
0
        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);
        }
Esempio n. 29
0
 public Block MineAndAddBlock(Block newBlock, UInt256 target = null)
 {
     var block = MineBlock(newBlock);
     AddBlock(block);
     return block;
 }