Beispiel #1
0
        private void QueryBlockTest_WithOprhanedPoolOutputCategory_ShouldGetOrphaned()
        {
            // test case: we supply a pending block which should stay as pending as pool output category is still 'immature'.
            var block = new PersistedBlock(1, false, false, false, "BLOCK_HASH", "TX_HASH", 0, 0, DateTime.Now);

            _poolConfig.Wallet.Adress.Returns("POOL_ADDRESS");

            _daemonClient.GetBlock("BLOCK_HASH").Returns(info => new Block {
                Tx = new List <string> {
                    "TX_HASH"
                }
            });
            _daemonClient.GetTransaction("TX_HASH").Returns(info => new Transaction
            {
                Details = new List <TransactionDetail> {
                    new TransactionDetail {
                        Address = "POOL_ADDRESS", Category = "orphan"
                    }
                }
            });

            // query the block.
            var exposed = Exposed.From(new BlockProcessor(_poolConfig, _daemonClient, _storageLayer));

            exposed.QueryBlock(block);

            // block should still stay as pending
            block.Status.Should().Equal(BlockStatus.Orphaned);
        }
Beispiel #2
0
        private void QueryBlockTest_WithIncorrectPoolOutputAccount_ShouldBeOrphaned()
        {
            // test case: generation transaction output doesn't match pool output account.
            var block = new PersistedBlock(1, false, false, false, "BLOCK_HASH", "TX_HASH", 0, 0, DateTime.Now);

            _daemonClient.GetBlock("BLOCK_HASH").Returns(info => new Block {
                Tx = new List <string> {
                    "TX_HASH"
                }
            });
            _daemonClient.GetTransaction("TX_HASH").Returns(info => new Transaction
            {
                Details = new List <TransactionDetail> {
                    new TransactionDetail {
                        Account = "DIFFERENT_ACCOUNT"
                    }
                }
            });

            // query the block.
            var exposed = Exposed.From(new BlockProcessor(_poolConfig, _daemonClient, _storageLayer));

            exposed._poolAccount = "POOL_ACCOUNT";
            exposed.QueryBlock(block);

            // block should be marked as orphaned.
            block.Status.Should().Equal(BlockStatus.Orphaned);
        }
Beispiel #3
0
        private void QueryBlockTest_ShouldSetReward()
        {
            // test case: set block reward based on pool output value.
            var block = new PersistedBlock(1, false, false, false, "BLOCK_HASH", "TX_HASH", 0, 0, DateTime.Now);

            _poolConfig.Wallet.Adress.Returns("POOL_ADDRESS");

            _daemonClient.GetBlock("BLOCK_HASH").Returns(info => new Block {
                Tx = new List <string> {
                    "TX_HASH"
                }
            });
            _daemonClient.GetTransaction("TX_HASH").Returns(info => new Transaction
            {
                Details = new List <TransactionDetail> {
                    new TransactionDetail {
                        Address = "POOL_ADDRESS", Amount = 999
                    }
                }
            });

            // query the block.
            var exposed = Exposed.From(new BlockProcessor(_poolConfig, _daemonClient, _storageLayer));

            exposed.QueryBlock(block);

            // block reward should be set to 999
            block.Reward.Should().Equal((decimal)999);
        }
Beispiel #4
0
        private void QueryBlockTest_WithNonExistingGenerationTransaction_ShouldBeOrphaned()
        {
            // test case: coin reports generation transaction hash as invalid.
            var block = new PersistedBlock(1, false, false, false, "BLOCK_HASH", "TX_HASH", 0, 0, DateTime.Now);

            _daemonClient.GetBlock("BLOCK_HASH").Returns(info => new Block {
                Tx = new List <string> {
                    "TX_HASH"
                }
            });

            _daemonClient.GetTransaction("TX_HASH").Returns(x =>
            {
                throw new RpcErrorException(new RpcErrorResponse
                {
                    Error = new RpcError
                    {
                        Code = -5 // 'Invalid or non-wallet transaction id'
                    }
                });
            });

            // query the block.
            var exposed = Exposed.From(new BlockProcessor(_poolConfig, _daemonClient, _storageLayer));

            exposed.QueryBlock(block);

            // block should be marked as orphaned.
            block.Status.Should().Equal(BlockStatus.Orphaned);
        }
        public async Task AddSecondaryBlock(Block block)
        {
            var persisted = new PersistedBlock(block, _addressEncoder);

            ForkChain.InsertOne(persisted);
            await Task.Yield();
        }
Beispiel #6
0
        private void QueryBlockTest_WithNegativeConfirmations_ShouldBeOrphaned()
        {
            // test case: coin daemon returns block-info with negative confirmations.
            var block = new PersistedBlock(1, false, false, false, "BLOCK_HASH", "TX_HASH", 0, 0, DateTime.Now);

            _daemonClient.GetBlock("BLOCK_HASH").Returns(info => new Block {
                Confirmations = -1
            });

            // query the block.
            var exposed = Exposed.From(new BlockProcessor(_poolConfig, _daemonClient, _storageLayer));

            exposed.QueryBlock(block);

            // block should be marked as orphaned.
            block.Status.Should().Equal(BlockStatus.Orphaned);
        }
        public async Task AddBlock(Block block)
        {
            var persisted  = new PersistedBlock(block, _addressEncoder);
            var prevHeader = MainChain
                             .Find(x => x.Header.BlockId == block.Header.PreviousBlock)
                             .Project(x => x.Header)
                             .FirstOrDefault();

            if (prevHeader != null)
            {
                persisted.Statistics.BlockTime = Convert.ToInt32(TimeSpan.FromTicks(block.Header.Timestamp - prevHeader.Timestamp).TotalSeconds);
            }

            MainChain.InsertOne(persisted);
            ForkChain.DeleteMany(x => x.Header.BlockId == block.Header.BlockId);

            await Task.Yield();
        }
Beispiel #8
0
        private void QueryBlockTest_WithInvalidTransactionHash_ShouldBeOrphaned()
        {
            // test case: coin daemon reports a different tx-hash then the one in block.
            var block = new PersistedBlock(1, false, false, false, "BLOCK_HASH", "TX_HASH", 0, 0, DateTime.Now);

            _daemonClient.GetBlock("BLOCK_HASH").Returns(info => new Block {
                Tx = new List <string> {
                    "DIFFERENT"
                }
            });

            // query the block.
            var exposed = Exposed.From(new BlockProcessor(_poolConfig, _daemonClient, _storageLayer));

            exposed.QueryBlock(block);

            // block should be marked as orphaned.
            block.Status.Should().Equal(BlockStatus.Orphaned);
        }
Beispiel #9
0
        private void QueryBlockTest_WithNonExistingPoolOutput_ShouldBeOrphaned()
        {
            // test case: generation transaction doesn't contain an output for the pool.
            var block = new PersistedBlock(1, false, false, false, "BLOCK_HASH", "TX_HASH", 0, 0, DateTime.Now);

            _daemonClient.GetBlock("BLOCK_HASH").Returns(info => new Block {
                Tx = new List <string> {
                    "TX_HASH"
                }
            });
            _daemonClient.GetTransaction("TX_HASH").Returns(info => new Transaction());

            // query the block.
            var exposed = Exposed.From(new BlockProcessor(_poolConfig, _daemonClient, _storageLayer));

            exposed.QueryBlock(block);

            // block should be marked as orphaned.
            block.Status.Should().Equal(BlockStatus.Orphaned);
        }
Beispiel #10
0
        private void QueryBlockTest_WithInvalidBlockHash_ShouldBeOrphaned()
        {
            // test case: coin daemon reports block hash as invalid.
            var block = new PersistedBlock(1, false, false, false, "INVALID_HASH", "TX_HASH", 0, 0, DateTime.Now);

            _daemonClient.GetBlock("INVALID_HASH").Returns(x =>
            {
                throw new RpcErrorException(new RpcErrorResponse
                {
                    Error = new RpcError
                    {
                        Code = -5 // 'block not found'.
                    }
                });
            });

            // query the block.
            var exposed = Exposed.From(new BlockProcessor(_poolConfig, _daemonClient, _storageLayer));

            exposed.QueryBlock(block);

            // block should be marked as orphaned.
            block.Status.Should().Equal(BlockStatus.Orphaned);
        }
Beispiel #11
0
        static void Main(string[] args)
        {
            Console.WriteLine("Begin");
            var rsa = RSA.Create();
            var key = rsa.ExportParameters(true);

            var ZeroHexHash = "";

            for (int i = 0; i < 64; i++)
            {
                ZeroHexHash += "0";
            }

            Console.WriteLine("Generating key files");

            #region Save Public Key
            string publicKey = RSAHelper.ExportPublicKeyToPEMFormat(rsa);

            FileInfo pem = new FileInfo("public.pem");
            if (pem.Exists)
            {
                pem.Delete();
            }

            using (var stream = pem.OpenWrite())
                using (var writer = new StreamWriter(stream))
                    writer.Write(publicKey);
            #endregion

            #region Save Private Key

            string privateKey = RSAHelper.ExportPrivateKeyToPfxFormat(rsa);

            FileInfo pfx = new FileInfo("private.pfx");
            if (pfx.Exists)
            {
                pfx.Delete();
            }

            using (var stream = pfx.OpenWrite())
                using (var writer = new StreamWriter(stream))
                    writer.Write(privateKey);

            #endregion

            Console.WriteLine("Public and private key file saved");

            Console.WriteLine("Mining Genesis block");
            #region Generate Genesis Block

            var transactionContent = new SycoinTransactionContent()
            {
                Outputs = new TransactionOutput[]
                {
                    new TransactionOutput
                    {
                        Amount   = 50,
                        Receiver = publicKey
                    }
                }
            };

            var contentHash = HashingHelper.HashObject(transactionContent);

            var transactions = new SyCoinTransaction[]
            {
                new SyCoinTransaction
                {
                    Content = transactionContent,
                    Hash    = HashingHelper.ByteArrayToHexDigit(contentHash)
                }
            };

            var blockData = new SyCoinBlock(transactions, 1, ZeroHexHash, 4);

            var(nonce, timestamp) = new BlockMiner().Mine(blockData);

            blockData.Seal(nonce, timestamp);

            PersistedBlock genesisBlock = new PersistedBlock()
            {
                Header = new BlockHeader(),
                Block  = blockData
            };

            FileInfo genesisJson = new FileInfo("genesis.json");
            if (genesisJson.Exists)
            {
                genesisJson.Delete();
            }

            using (var stream = genesisJson.OpenWrite())
                using (var writer = new StreamWriter(stream))
                    writer.Write(Newtonsoft.Json.JsonConvert.SerializeObject(genesisBlock));

            #endregion

            Console.WriteLine("Genesis block saved in genesis.json");
            Console.ReadLine();
        }
 public void AddBlock(PersistedBlock newBlock)
 {
     GetLedgerCollection().InsertOne(newBlock);
 }