public async Task PostTransaction_ValidationException()
        {
            TransactionValidator validator = new TransactionValidator(
                new TestStore(defaultAccounts, false),
                new TestValidator(true),
                validNamespace);

            ByteString mutation = CreateMutation(validNamespace);

            TransactionInvalidException exception = await Assert.ThrowsAsync<TransactionInvalidException>(
                () => validator.PostTransaction(mutation, new SignatureEvidence[0]));
            Assert.Equal("Test", exception.Reason);
        }
Exemple #2
0
        public async Task Can_process_mined_blocks()
        {
            int timeMultiplier = 1; // for debugging

            TimeSpan miningDelay = TimeSpan.FromMilliseconds(50 * timeMultiplier);

            /* logging & instrumentation */
//            OneLoggerLogManager logger = new OneLoggerLogManager(new SimpleConsoleLogger(true));
            ILogManager logManager = NullLogManager.Instance;
            ILogger     logger     = logManager.GetClassLogger();

            /* spec */
            FakeSealer sealer = new FakeSealer(miningDelay);

            RopstenSpecProvider specProvider = RopstenSpecProvider.Instance;

            /* store & validation */

            EthereumEcdsa   ethereumEcdsa   = new EthereumEcdsa(specProvider, logManager);
            MemDb           receiptsDb      = new MemDb();
            MemDb           traceDb         = new MemDb();
            TransactionPool transactionPool = new TransactionPool(new NullTransactionStorage(),
                                                                  new PendingTransactionThresholdValidator(), new Timestamp(), ethereumEcdsa, specProvider, logManager);
            IReceiptStorage      receiptStorage       = new PersistentReceiptStorage(receiptsDb, specProvider);
            BlockTree            blockTree            = new BlockTree(new MemDb(), new MemDb(), specProvider, transactionPool, logManager);
            Timestamp            timestamp            = new Timestamp();
            DifficultyCalculator difficultyCalculator = new DifficultyCalculator(specProvider);
            HeaderValidator      headerValidator      = new HeaderValidator(blockTree, sealer, specProvider, logManager);
            OmmersValidator      ommersValidator      = new OmmersValidator(blockTree, headerValidator, logManager);
            TransactionValidator transactionValidator = new TransactionValidator(new SignatureValidator(ChainId.Ropsten));
            BlockValidator       blockValidator       = new BlockValidator(transactionValidator, headerValidator, ommersValidator, specProvider, logManager);

            /* state & storage */
            StateDb         codeDb          = new StateDb();
            StateDb         stateDb         = new StateDb();
            StateTree       stateTree       = new StateTree(stateDb);
            StateProvider   stateProvider   = new StateProvider(stateTree, codeDb, logManager);
            StorageProvider storageProvider = new StorageProvider(stateDb, stateProvider, logManager);

            TestTransactionsGenerator generator = new TestTransactionsGenerator(transactionPool, ethereumEcdsa, TimeSpan.FromMilliseconds(5 * timeMultiplier), NullLogManager.Instance);

            generator.Start();

            /* blockchain processing */
            BlockhashProvider    blockhashProvider = new BlockhashProvider(blockTree);
            VirtualMachine       virtualMachine    = new VirtualMachine(stateProvider, storageProvider, blockhashProvider, logManager);
            TransactionProcessor processor         = new TransactionProcessor(specProvider, stateProvider, storageProvider, virtualMachine, logManager);
            RewardCalculator     rewardCalculator  = new RewardCalculator(specProvider);
            BlockProcessor       blockProcessor    = new BlockProcessor(specProvider, blockValidator, rewardCalculator,
                                                                        processor, stateDb, codeDb, traceDb, stateProvider, storageProvider, transactionPool, receiptStorage, logManager);
            BlockchainProcessor blockchainProcessor = new BlockchainProcessor(blockTree, blockProcessor, new TxSignaturesRecoveryStep(ethereumEcdsa, NullTransactionPool.Instance), logManager, false, false);

            /* load ChainSpec and init */
            ChainSpecLoader loader = new ChainSpecLoader(new EthereumJsonSerializer());
            string          path   = "chainspec.json";

            logManager.GetClassLogger().Info($"Loading ChainSpec from {path}");
            ChainSpec chainSpec = loader.Load(File.ReadAllBytes(path));

            foreach (var allocation in chainSpec.Allocations)
            {
                stateProvider.CreateAccount(allocation.Key, allocation.Value);
            }

            stateProvider.Commit(specProvider.GenesisSpec);
            chainSpec.Genesis.Header.StateRoot = stateProvider.StateRoot; // TODO: shall it be HeaderSpec and not BlockHeader?
            chainSpec.Genesis.Header.Hash      = BlockHeader.CalculateHash(chainSpec.Genesis.Header);
            if (chainSpec.Genesis.Hash != new Keccak("0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d"))
            {
                throw new Exception("Unexpected genesis hash");
            }

            /* start processing */
            blockTree.SuggestBlock(chainSpec.Genesis);
            blockchainProcessor.Start();

            MinedBlockProducer minedBlockProducer = new MinedBlockProducer(difficultyCalculator, transactionPool, blockchainProcessor, sealer, blockTree, timestamp, NullLogManager.Instance);

            minedBlockProducer.Start();

            ManualResetEventSlim manualResetEvent = new ManualResetEventSlim(false);

            blockTree.NewHeadBlock += (sender, args) =>
            {
                if (args.Block.Number == 6)
                {
                    manualResetEvent.Set();
                }
            };

            manualResetEvent.Wait(miningDelay * 12 * timeMultiplier);
            await minedBlockProducer.StopAsync();

            int previousCount = 0;
            int totalTx       = 0;

            for (int i = 0; i < 6; i++)
            {
                Block block = blockTree.FindBlock(new UInt256(i));
                logger.Info($"Block {i} with {block.Transactions.Length} txs");

                ManualResetEventSlim blockProcessedEvent = new ManualResetEventSlim(false);
                blockchainProcessor.ProcessingQueueEmpty += (sender, args) => blockProcessedEvent.Set();
                blockchainProcessor.SuggestBlock(block.Hash, ProcessingOptions.ForceProcessing | ProcessingOptions.StoreReceipts | ProcessingOptions.ReadOnlyChain);
                blockProcessedEvent.Wait(1000);

                Tracer tracer = new Tracer(blockchainProcessor, receiptStorage, blockTree, new MemDb());

                int currentCount = receiptsDb.Keys.Count;
                logger.Info($"Current count of receipts {currentCount}");
                logger.Info($"Previous count of receipts {previousCount}");

                if (block.Transactions.Length > 0)
                {
                    GethLikeTxTrace trace = tracer.Trace(block.Transactions[0].Hash);
                    Assert.AreSame(GethLikeTxTrace.QuickFail, trace);
                    Assert.AreNotEqual(previousCount, currentCount, $"receipts at block {i}");
                    totalTx += block.Transactions.Length;
                }

                previousCount = currentCount;
            }

            Assert.AreNotEqual(0, totalTx, "no tx in blocks");
        }
Exemple #3
0
        public async Task Build_some_chain()
        {
            /* logging & instrumentation */
            var logger = new OneLoggerLogManager(new SimpleConsoleLogger());

            /* spec */
            var blockMiningTime = TimeSpan.FromMilliseconds(500);
            var sealEngine      = new FakeSealEngine(blockMiningTime);
            var specProvider    = RopstenSpecProvider.Instance;

            /* store & validation */
            var blockTree            = new BlockTree(new MemDb(), new MemDb(), new MemDb(), specProvider, logger);
            var difficultyCalculator = new DifficultyCalculator(specProvider);
            var headerValidator      = new HeaderValidator(difficultyCalculator, blockTree, sealEngine, specProvider, logger);
            var ommersValidator      = new OmmersValidator(blockTree, headerValidator, logger);
            var transactionValidator = new TransactionValidator(new SignatureValidator(ChainId.Ropsten));
            var blockValidator       = new BlockValidator(transactionValidator, headerValidator, ommersValidator, specProvider, logger);

            /* state & storage */
            var dbProvider      = new MemDbProvider(logger);
            var stateTree       = new StateTree(dbProvider.GetOrCreateStateDb());
            var stateProvider   = new StateProvider(stateTree, dbProvider.GetOrCreateCodeDb(), logger);
            var storageProvider = new StorageProvider(dbProvider, stateProvider, logger);

            /* blockchain processing */
            var ethereumSigner      = new EthereumSigner(specProvider, logger);
            var transactionStore    = new TransactionStore();
            var blockhashProvider   = new BlockhashProvider(blockTree);
            var virtualMachine      = new VirtualMachine(stateProvider, storageProvider, blockhashProvider, logger);
            var processor           = new TransactionProcessor(specProvider, stateProvider, storageProvider, virtualMachine, NullTracer.Instance, logger);
            var rewardCalculator    = new RewardCalculator(specProvider);
            var blockProcessor      = new BlockProcessor(specProvider, blockValidator, rewardCalculator, processor, dbProvider, stateProvider, storageProvider, transactionStore, logger);
            var blockchainProcessor = new BlockchainProcessor(blockTree, sealEngine, transactionStore, difficultyCalculator, blockProcessor, ethereumSigner, logger);

            /* load ChainSpec and init */
            ChainSpecLoader loader = new ChainSpecLoader(new UnforgivingJsonSerializer());
            string          path   = Path.Combine(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"..\..\..\..\Chains", "ropsten.json"));

            logger.GetClassLogger().Info($"Loading ChainSpec from {path}");
            ChainSpec chainSpec = loader.Load(File.ReadAllBytes(path));

            foreach (KeyValuePair <Address, BigInteger> allocation in chainSpec.Allocations)
            {
                stateProvider.CreateAccount(allocation.Key, allocation.Value);
            }

            stateProvider.Commit(specProvider.GenesisSpec);
            chainSpec.Genesis.Header.StateRoot = stateProvider.StateRoot; // TODO: shall it be HeaderSpec and not BlockHeader?
            chainSpec.Genesis.Header.Hash      = BlockHeader.CalculateHash(chainSpec.Genesis.Header);
            if (chainSpec.Genesis.Hash != new Keccak("0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d"))
            {
                throw new Exception("Unexpected genesis hash");
            }

            /* start processing */
            sealEngine.IsMining = true;
            var testTransactionsGenerator = new TestTransactionsGenerator(transactionStore, ethereumSigner, blockMiningTime, logger);

            testTransactionsGenerator.Start();

            blockchainProcessor.Start();
            blockTree.SuggestBlock(chainSpec.Genesis);

            BigInteger roughlyNumberOfBlocks = 6;

            Thread.Sleep(blockMiningTime * (int)roughlyNumberOfBlocks);
            await blockchainProcessor.StopAsync(false);

            Assert.GreaterOrEqual(blockTree.Head.Number, roughlyNumberOfBlocks - 2, "number of blocks");
            Assert.GreaterOrEqual(blockTree.Head.TotalTransactions, roughlyNumberOfBlocks - 2, "number of transactions");
        }
Exemple #4
0
        private async Task InitBlockchain()
        {
            ChainSpec chainSpec = LoadChainSpec(_initConfig.ChainSpecPath);

            /* spec */
            // TODO: rebuild to use chainspec
            ISpecProvider specProvider;

            if (chainSpec.ChainId == RopstenSpecProvider.Instance.ChainId)
            {
                specProvider = RopstenSpecProvider.Instance;
            }
            else if (chainSpec.ChainId == MainNetSpecProvider.Instance.ChainId)
            {
                specProvider = MainNetSpecProvider.Instance;
            }
            else
            {
                throw new NotSupportedException($"Not yet tested, not yet supported ChainId {chainSpec.ChainId}");
            }

            var ethereumSigner = new EthereumSigner(
                specProvider,
                _logManager);

            var transactionStore = new TransactionStore();

            var sealEngine = ConfigureSealEngine(
                transactionStore,
                ethereumSigner);

            /* sync */
            IDbConfig dbConfig = _configProvider.GetConfig <IDbConfig>();

            foreach (PropertyInfo propertyInfo in typeof(IDbConfig).GetProperties())
            {
                _logger.Info($"DB {propertyInfo.Name}: {propertyInfo.GetValue(dbConfig)}");
            }

            var blocksDb = new DbOnTheRocks(
                Path.Combine(_dbBasePath, DbOnTheRocks.BlocksDbPath),
                dbConfig);

            var blockInfosDb = new DbOnTheRocks(
                Path.Combine(_dbBasePath, DbOnTheRocks.BlockInfosDbPath),
                dbConfig);

            var receiptsDb = new DbOnTheRocks(
                Path.Combine(_dbBasePath, DbOnTheRocks.ReceiptsDbPath),
                dbConfig);

            /* blockchain */
            _blockTree = new BlockTree(
                blocksDb,
                blockInfosDb,
                receiptsDb,
                specProvider,
                _logManager);

            var difficultyCalculator = new DifficultyCalculator(
                specProvider);

            /* validation */
            var headerValidator = new HeaderValidator(
                difficultyCalculator,
                _blockTree,
                sealEngine,
                specProvider,
                _logManager);

            var ommersValidator = new OmmersValidator(
                _blockTree,
                headerValidator,
                _logManager);

            var txValidator = new TransactionValidator(
                new SignatureValidator(specProvider.ChainId));

            var blockValidator = new BlockValidator(
                txValidator,
                headerValidator,
                ommersValidator,
                specProvider,
                _logManager);

            /* state */
            var dbProvider = new RocksDbProvider(
                _dbBasePath,
                _logManager,
                dbConfig);

            var stateDb = dbProvider.GetOrCreateStateDb();

            var stateTree = new StateTree(stateDb);

            var stateProvider = new StateProvider(
                stateTree,
                dbProvider.GetOrCreateCodeDb(),
                _logManager);

            var storageProvider = new StorageProvider(
                dbProvider,
                stateProvider,
                _logManager);

            /* blockchain processing */
            var blockhashProvider = new BlockhashProvider(
                _blockTree);

            var virtualMachine = new VirtualMachine(
                stateProvider,
                storageProvider,
                blockhashProvider,
                _logManager);

            var transactionProcessor = new TransactionProcessor(
                specProvider,
                stateProvider,
                storageProvider,
                virtualMachine,
                _tracer,
                _logManager);

            var rewardCalculator = new RewardCalculator(
                specProvider);

            var blockProcessor = new BlockProcessor(
                specProvider,
                blockValidator,
                rewardCalculator,
                transactionProcessor,
                dbProvider,
                stateProvider,
                storageProvider,
                transactionStore,
                _logManager);

            _blockchainProcessor = new BlockchainProcessor(
                _blockTree,
                sealEngine,
                transactionStore,
                difficultyCalculator,
                blockProcessor,
                ethereumSigner,
                _logManager, _perfService);

            // create shared objects between discovery and peer manager
            _nodeFactory       = new NodeFactory();
            _nodeStatsProvider = new NodeStatsProvider(_configProvider.GetConfig <IStatsConfig>(), _nodeFactory, _logManager);

            var jsonSerializer = new JsonSerializer(
                _logManager);

            var encrypter = new AesEncrypter(
                _configProvider,
                _logManager);

            _keyStore = new FileKeyStore(
                _configProvider,
                jsonSerializer,
                encrypter,
                _cryptoRandom,
                _logManager);

            //creating blockchain bridge
            BlockchainBridge = new BlockchainBridge(
                ethereumSigner,
                stateProvider,
                _keyStore,
                _blockTree,
                stateDb,
                transactionStore);

            EthereumSigner = ethereumSigner;

            _blockchainProcessor.Start();
            LoadGenesisBlock(chainSpec,
                             string.IsNullOrWhiteSpace(_initConfig.GenesisHash) ? null : new Keccak(_initConfig.GenesisHash),
                             _blockTree, stateProvider, specProvider);

#pragma warning disable 4014
            LoadBlocksFromDb();
#pragma warning restore 4014

            await InitializeNetwork(
                transactionStore,
                blockValidator,
                headerValidator,
                txValidator);
        }
Exemple #5
0
        private async Task InitializeNetwork(
            TransactionStore transactionStore,
            BlockValidator blockValidator,
            HeaderValidator headerValidator,
            TransactionValidator txValidator)
        {
            if (!_initConfig.NetworkEnabled)
            {
                if (_logger.IsInfo)
                {
                    _logger.Info($"Skipping blockchain synchronization init ({nameof(IInitConfig.NetworkEnabled)} = false)");
                }
                return;
            }

            _syncManager = new SynchronizationManager(
                _blockTree,
                blockValidator,
                headerValidator,
                transactionStore,
                txValidator,
                _logManager,
                _configProvider.GetConfig <IBlockchainConfig>(), _perfService);

            InitDiscovery();
            await InitPeer();

            await StartSync().ContinueWith(initNetTask =>
            {
                if (initNetTask.IsFaulted)
                {
                    _logger.Error("Unable to start sync.", initNetTask.Exception);
                }
            });

            await StartDiscovery().ContinueWith(initDiscoveryTask =>
            {
                if (initDiscoveryTask.IsFaulted)
                {
                    _logger.Error("Unable to start discovery protocol.", initDiscoveryTask.Exception);
                }
            });

            await StartPeer().ContinueWith(initPeerManagerTask =>
            {
                if (initPeerManagerTask.IsFaulted)
                {
                    _logger.Error("Unable to start peer manager.", initPeerManagerTask.Exception);
                }
            });

            var localIp = _networkHelper.GetLocalIp();

            if (_logger.IsInfo)
            {
                _logger.Info($"Node is up and listening on {localIp}:{_initConfig.P2PPort}");
            }
            if (_logger.IsInfo)
            {
                _logger.Info($"enode://{_privateKey.PublicKey}@{localIp}:{_initConfig.P2PPort}");
            }
        }
Exemple #6
0
 private static void ValidateIfBundleEntryIsUnique(Core.Models.ResourceElement requestBundle)
 {
     TransactionValidator.ValidateTransactionBundle(requestBundle.ToPoco <Hl7.Fhir.Model.Bundle>());
 }
 public TedchainController(IStorageEngine store, ILogger logger, TransactionValidator validator = null)
 {
     this.store     = store;
     this.validator = validator;
     this.logger    = logger;
 }
        protected async Task RunTest(BlockchainTest test, Stopwatch stopwatch = null)
        {
            Assert.IsNull(test.LoadFailure, "test data loading failure");

            // TODO: not supported in .NET Core, need to replace?
            // LoggingTraceListener traceListener = new LoggingTraceListener();
            // Debug.Listeners.Clear();
            // Debug.Listeners.Add(traceListener);

            ISnapshotableDb stateDb   = new StateDb();
            ISnapshotableDb codeDb    = new StateDb();
            IDb             traceDb   = new MemDb();
            StateTree       stateTree = new StateTree(stateDb);


            ISpecProvider specProvider;

            if (test.NetworkAfterTransition != null)
            {
                specProvider = new CustomSpecProvider(
                    (0, Frontier.Instance),
                    (1, test.Network),
                    (test.TransitionBlockNumber, test.NetworkAfterTransition));
            }
            else
            {
                specProvider = new CustomSpecProvider(
                    (0, Frontier.Instance), // TODO: this thing took a lot of time to find after it was removed!, genesis block is always initialized with Frontier
                    (1, test.Network));
            }

            if (specProvider.GenesisSpec != Frontier.Instance)
            {
                Assert.Fail("Expected genesis spec to be Frontier for blockchain tests");
            }

            DifficultyCalculator.Wrapped = new DifficultyCalculator(specProvider);
            IRewardCalculator rewardCalculator = new RewardCalculator(specProvider);


            IEthereumEcdsa   ecdsa           = new EthereumEcdsa(specProvider, _logManager);
            ITransactionPool transactionPool = new TransactionPool(NullTransactionStorage.Instance,
                                                                   new PendingTransactionThresholdValidator(), new Timestamp(), ecdsa, specProvider, _logManager);

            IReceiptStorage       receiptStorage       = NullReceiptStorage.Instance;
            IBlockTree            blockTree            = new BlockTree(new MemDb(), new MemDb(), specProvider, transactionPool, _logManager);
            IBlockhashProvider    blockhashProvider    = new BlockhashProvider(blockTree);
            ISignatureValidator   signatureValidator   = new SignatureValidator(ChainId.MainNet);
            ITransactionValidator transactionValidator = new TransactionValidator(signatureValidator);
            IHeaderValidator      headerValidator      = new HeaderValidator(blockTree, Sealer, specProvider, _logManager);
            IOmmersValidator      ommersValidator      = new OmmersValidator(blockTree, headerValidator, _logManager);
            IBlockValidator       blockValidator       = new BlockValidator(transactionValidator, headerValidator, ommersValidator, specProvider, _logManager);
            IStateProvider        stateProvider        = new StateProvider(stateTree, codeDb, _logManager);
            IStorageProvider      storageProvider      = new StorageProvider(stateDb, stateProvider, _logManager);
            IVirtualMachine       virtualMachine       = new VirtualMachine(
                stateProvider,
                storageProvider,
                blockhashProvider,
                _logManager);

            IBlockProcessor blockProcessor = new BlockProcessor(
                specProvider,
                blockValidator,
                rewardCalculator,
                new TransactionProcessor(
                    specProvider,
                    stateProvider,
                    storageProvider,
                    virtualMachine,
                    _logManager),
                stateDb,
                codeDb,
                traceDb,
                stateProvider,
                storageProvider,
                transactionPool,
                receiptStorage,
                _logManager);

            IBlockchainProcessor blockchainProcessor = new BlockchainProcessor(
                blockTree,
                blockProcessor,
                new TxSignaturesRecoveryStep(ecdsa, NullTransactionPool.Instance),
                _logManager,
                false,
                false);

            InitializeTestState(test, stateProvider, storageProvider, specProvider);

            List <(Block Block, string ExpectedException)> correctRlpsBlocks = new List <(Block, string)>();

            for (int i = 0; i < test.Blocks.Length; i++)
            {
                try
                {
                    TestBlockJson testBlockJson  = test.Blocks[i];
                    var           rlpContext     = Bytes.FromHexString(testBlockJson.Rlp).AsRlpContext();
                    Block         suggestedBlock = Rlp.Decode <Block>(rlpContext);
                    suggestedBlock.Header.SealEngineType = test.SealEngineUsed ? SealEngineType.Ethash : SealEngineType.None;

                    Assert.AreEqual(new Keccak(testBlockJson.BlockHeader.Hash), suggestedBlock.Header.Hash, "hash of the block");
                    for (int ommerIndex = 0; ommerIndex < suggestedBlock.Ommers.Length; ommerIndex++)
                    {
                        Assert.AreEqual(new Keccak(testBlockJson.UncleHeaders[ommerIndex].Hash), suggestedBlock.Ommers[ommerIndex].Hash, "hash of the ommer");
                    }

                    correctRlpsBlocks.Add((suggestedBlock, testBlockJson.ExpectedException));
                }
                catch (Exception)
                {
                    _logger?.Info($"Invalid RLP ({i})");
                }
            }

            if (correctRlpsBlocks.Count == 0)
            {
                Assert.AreEqual(new Keccak(test.GenesisBlockHeader.Hash), test.LastBlockHash);
                return;
            }

            if (test.GenesisRlp == null)
            {
                test.GenesisRlp = Rlp.Encode(new Block(Convert(test.GenesisBlockHeader)));
            }

            Block genesisBlock = Rlp.Decode <Block>(test.GenesisRlp.Bytes);

            Assert.AreEqual(new Keccak(test.GenesisBlockHeader.Hash), genesisBlock.Header.Hash, "genesis header hash");

            ManualResetEvent genesisProcessed = new ManualResetEvent(false);

            blockTree.NewHeadBlock += (sender, args) =>
            {
                if (args.Block.Number == 0)
                {
                    Assert.AreEqual(genesisBlock.Header.StateRoot, stateTree.RootHash, "genesis state root");
                    genesisProcessed.Set();
                }
            };

            blockchainProcessor.Start();
            blockTree.SuggestBlock(genesisBlock);

            genesisProcessed.WaitOne();

            for (int i = 0; i < correctRlpsBlocks.Count; i++)
            {
                stopwatch?.Start();
                try
                {
                    if (correctRlpsBlocks[i].ExpectedException != null)
                    {
                        _logger.Info($"Expecting block exception: {correctRlpsBlocks[i].ExpectedException}");
                    }

                    if (correctRlpsBlocks[i].Block.Hash == null)
                    {
                        throw new Exception($"null hash in {test.Name} block {i}");
                    }

                    // TODO: mimic the actual behaviour where block goes through validating sync manager?
                    if (!test.SealEngineUsed || blockValidator.ValidateSuggestedBlock(correctRlpsBlocks[i].Block))
                    {
                        blockTree.SuggestBlock(correctRlpsBlocks[i].Block);
                    }
                    else
                    {
                        Console.WriteLine("Invalid block");
                    }
                }
                catch (InvalidBlockException)
                {
                }
                catch (Exception ex)
                {
                    _logger?.Info(ex.ToString());
                }
            }

            await blockchainProcessor.StopAsync(true);

            stopwatch?.Stop();

            List <string> differences = RunAssertions(test, blockTree.RetrieveHeadBlock(), storageProvider, stateProvider);

//            if (differences.Any())
//            {
//                BlockTrace blockTrace = blockchainProcessor.TraceBlock(blockTree.BestSuggested.Hash);
//                _logger.Info(new UnforgivingJsonSerializer().Serialize(blockTrace, true));
//            }

            Assert.Zero(differences.Count, "differences");
        }
Exemple #9
0
 public TransactionManager()
 {
     TransactionValidator = new TransactionValidator();
 }
Exemple #10
0
        private bool CheckIssueDate(NZString TranID)
        {
            TransactionValidator val = new TransactionValidator();

            return(val.TransactionCanEditOrDelete(TranID));
        }
        public async Task <ActionResult> Post()
        {
            JObject body;

            try
            {
                string bodyContent;
                using (StreamReader streamReader = new StreamReader(Request.Body))
                    bodyContent = await streamReader.ReadToEndAsync();

                body = JObject.Parse(bodyContent);
            }
            catch (JsonReaderException)
            {
                return(HttpBadRequest());
            }

            TransactionValidator validator = HttpContext.ApplicationServices.GetService <TransactionValidator>();

            if (validator == null)
            {
                return(CreateErrorResponse("ValidationDisabled"));
            }

            ByteString parsedTransaction;
            List <SignatureEvidence> authentication = new List <SignatureEvidence>();

            if (!(body["mutation"] is JValue && body["signatures"] is JArray))
            {
                return(HttpBadRequest());
            }

            try
            {
                parsedTransaction = ByteString.Parse((string)body["mutation"]);

                foreach (JToken signatureItem in body["signatures"])
                {
                    JObject evidence = signatureItem as JObject;
                    if (!(evidence != null && evidence["pub_key"] is JValue && evidence["signature"] is JValue))
                    {
                        return(HttpBadRequest());
                    }

                    authentication.Add(new SignatureEvidence(
                                           ByteString.Parse((string)evidence["pub_key"]),
                                           ByteString.Parse((string)evidence["signature"])));
                }
            }
            catch (FormatException)
            {
                return(HttpBadRequest());
            }

            ByteString transactionId;

            try
            {
                transactionId = await validator.PostTransaction(parsedTransaction, authentication);
            }
            catch (TransactionInvalidException exception)
            {
                logger.LogInformation("Rejected transaction: {0}", exception.Message);

                return(CreateErrorResponse(exception.Reason));
            }

            logger.LogInformation("Validated transaction {0}", transactionId.ToString());

            return(Json(new
            {
                transaction_hash = transactionId.ToString()
            }));
        }
Exemple #12
0
        public async Task Test()
        {
            TimeSpan miningDelay = TimeSpan.FromMilliseconds(50);

            /* logging & instrumentation */
            var logger = new OneLoggerLogManager(new SimpleConsoleLogger(true));

            /* spec */
            var sealEngine = new FakeSealEngine(miningDelay);

            sealEngine.IsMining = true;

            var specProvider = RopstenSpecProvider.Instance;

            /* store & validation */
            var blockTree            = new BlockTree(new MemDb(), new MemDb(), new MemDb(), specProvider, logger);
            var difficultyCalculator = new DifficultyCalculator(specProvider);
            var headerValidator      = new HeaderValidator(difficultyCalculator, blockTree, sealEngine, specProvider, logger);
            var ommersValidator      = new OmmersValidator(blockTree, headerValidator, logger);
            var transactionValidator = new TransactionValidator(new SignatureValidator(ChainId.Ropsten));
            var blockValidator       = new BlockValidator(transactionValidator, headerValidator, ommersValidator, specProvider, logger);

            /* state & storage */
            var codeDb            = new MemDb();
            var stateDb           = new MemDb();
            var stateTree         = new StateTree(stateDb);
            var stateProvider     = new StateProvider(stateTree, codeDb, logger);
            var storageDbProvider = new MemDbProvider(logger);
            var storageProvider   = new StorageProvider(storageDbProvider, stateProvider, logger);

            /* blockchain processing */
            var ethereumSigner      = new EthereumSigner(specProvider, logger);
            var transactionStore    = new TransactionStore();
            var blockhashProvider   = new BlockhashProvider(blockTree);
            var virtualMachine      = new VirtualMachine(stateProvider, storageProvider, blockhashProvider, logger);
            var processor           = new TransactionProcessor(specProvider, stateProvider, storageProvider, virtualMachine, NullTracer.Instance, logger);
            var rewardCalculator    = new RewardCalculator(specProvider);
            var blockProcessor      = new BlockProcessor(specProvider, blockValidator, rewardCalculator, processor, storageDbProvider, stateProvider, storageProvider, transactionStore, logger);
            var blockchainProcessor = new BlockchainProcessor(blockTree, sealEngine, transactionStore, difficultyCalculator, blockProcessor, ethereumSigner, logger, new PerfService(NullLogManager.Instance));

            /* load ChainSpec and init */
            ChainSpecLoader loader = new ChainSpecLoader(new UnforgivingJsonSerializer());
            string          path   = Path.Combine(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"..\..\..\..\Chains", "ropsten.json"));

            logger.GetClassLogger().Info($"Loading ChainSpec from {path}");
            ChainSpec chainSpec = loader.Load(File.ReadAllBytes(path));

            foreach (KeyValuePair <Address, UInt256> allocation in chainSpec.Allocations)
            {
                stateProvider.CreateAccount(allocation.Key, allocation.Value);
            }

            stateProvider.Commit(specProvider.GenesisSpec);
            chainSpec.Genesis.Header.StateRoot = stateProvider.StateRoot; // TODO: shall it be HeaderSpec and not BlockHeader?
            chainSpec.Genesis.Header.Hash      = BlockHeader.CalculateHash(chainSpec.Genesis.Header);
            if (chainSpec.Genesis.Hash != new Keccak("0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d"))
            {
                throw new Exception("Unexpected genesis hash");
            }

            /* start processing */
            blockTree.SuggestBlock(chainSpec.Genesis);
            blockchainProcessor.Start();

            ManualResetEvent manualResetEvent = new ManualResetEvent(false);

            blockTree.NewHeadBlock += (sender, args) =>
            {
                if (args.Block.Number == 6)
                {
                    manualResetEvent.Set();
                }
            };

            manualResetEvent.WaitOne(miningDelay * 12);

            await blockchainProcessor.StopAsync(true).ContinueWith(
                t =>
            {
                if (t.IsFaulted)
                {
                    throw t.Exception;
                }

                Assert.GreaterOrEqual((int)blockTree.Head.Number, 6);
            });
        }
        public async Task PostTransaction_ConcurrencyException()
        {
            this.store = new TestStore(defaultAccounts, true);
            TransactionValidator validator = new TransactionValidator(
                this.store,
                new TestValidator(false),
                validNamespace);

            ByteString mutation = CreateMutation(validNamespace);

            TransactionInvalidException exception = await Assert.ThrowsAsync<TransactionInvalidException>(
                () => validator.PostTransaction(mutation, new SignatureEvidence[0]));
            Assert.Equal("OptimisticConcurrency", exception.Reason);
            Assert.Equal(1, store.AddedTransactions.Count);
        }
        public TransactionPolicyError[] Check(TransactionValidator validator)
        {
            if (validator == null)
            {
                throw new ArgumentNullException(nameof(validator));
            }
            var transaction = validator.Transaction;
            List <TransactionPolicyError> errors = new List <TransactionPolicyError>();

            foreach (var input in validator.Transaction.Inputs.AsIndexedInputs())
            {
                if (this.ScriptVerify is NBitcoin.ScriptVerify)
                {
                    ScriptError?error;
                    if (!VerifyScript(validator, (int)input.Index, out error) && error is ScriptError err)
                    {
                        errors.Add(new ScriptPolicyError(input, err, validator.ScriptVerify, validator.SpentOutputs[input.Index].ScriptPubKey));
                    }
                }
                var txin = input.TxIn;
                if (txin.ScriptSig.Length > MaxScriptSigLength)
                {
                    errors.Add(new InputPolicyError("Max scriptSig length exceeded actual is " + txin.ScriptSig.Length + ", max is " + MaxScriptSigLength, input));
                }
                if (!txin.ScriptSig.IsPushOnly)
                {
                    errors.Add(new InputPolicyError("All operation should be push", input));
                }
                if (!txin.ScriptSig.HasCanonicalPushes)
                {
                    errors.Add(new InputPolicyError("All operation should be canonical push", input));
                }
            }

            if (CheckScriptPubKey)
            {
                foreach (var txout in transaction.Outputs.AsCoins())
                {
                    if (!Strategy.IsStandardOutput(txout.TxOut))
                    {
                        errors.Add(new OutputPolicyError("Non-Standard scriptPubKey", (int)txout.Outpoint.N));
                    }
                }
            }

            int txSize = transaction.GetSerializedSize();

            if (MaxTransactionSize != null)
            {
                if (txSize >= MaxTransactionSize.Value)
                {
                    errors.Add(new TransactionSizePolicyError(txSize, MaxTransactionSize.Value));
                }
            }

            var fees = transaction.GetFee(validator.SpentOutputs);

            if (fees != null)
            {
                var virtualSize = transaction.GetVirtualSize();
                if (CheckFee)
                {
                    if (MaxTxFee != null)
                    {
                        var max = MaxTxFee.GetFee(virtualSize);
                        if (fees > max)
                        {
                            errors.Add(new FeeTooHighPolicyError(fees, max));
                        }
                    }

                    if (MinFee != null)
                    {
                        if (fees < MinFee)
                        {
                            errors.Add(new FeeTooLowPolicyError(fees, MinFee));
                        }
                    }

                    if (MinRelayTxFee != null)
                    {
                        if (MinRelayTxFee != null)
                        {
                            var min = MinRelayTxFee.GetFee(virtualSize);
                            if (fees < min)
                            {
                                errors.Add(new FeeTooLowPolicyError(fees, min));
                            }
                        }
                    }
                }
            }
            if (MinRelayTxFee != null)
            {
                foreach (var output in transaction.Outputs)
                {
                    var bytes = output.ScriptPubKey.ToBytes(true);
                    if (output.IsDust(MinRelayTxFee) && !IsOpReturn(bytes))
                    {
                        errors.Add(new DustPolicyError(output.Value, output.GetDustThreshold(MinRelayTxFee)));
                    }
                }
            }
            var opReturnCount = transaction.Outputs.Select(o => o.ScriptPubKey.ToBytes(true)).Count(b => IsOpReturn(b));

            if (opReturnCount > 1)
            {
                errors.Add(new TransactionPolicyError("More than one op return detected"));
            }
            return(errors.ToArray());
        }