public void Setup_chain() { // Import blocks _blockTree = Build.A.BlockTree().TestObject; Block block1 = Rlp.Decode <Block>(new Rlp(Bytes.FromHexString(Block1Rlp))); Block block2 = Rlp.Decode <Block>(new Rlp(Bytes.FromHexString(Block2Rlp))); Block block3 = Rlp.Decode <Block>(new Rlp(Bytes.FromHexString(Block3Rlp))); Block block4 = Rlp.Decode <Block>(new Rlp(Bytes.FromHexString(Block4Rlp))); Block block5 = Rlp.Decode <Block>(new Rlp(Bytes.FromHexString(Block5Rlp))); Block genesisBlock = GetRinkebyGenesis(); // Add blocks MineBlock(_blockTree, genesisBlock); MineBlock(_blockTree, block1); MineBlock(_blockTree, block2); MineBlock(_blockTree, block3); MineBlock(_blockTree, block4); MineBlock(_blockTree, block5); // Get a test private key PrivateKey key = Build.A.PrivateKey.TestObject; // Init snapshot db MemDb db = new MemDb(); CliqueConfig config = new CliqueConfig(); _signer = new EthereumSigner(RinkebySpecProvider.Instance, LimboLogs.Instance); _clique = new CliqueSealEngine(config, _signer, key, db, _blockTree, LimboLogs.Instance); }
public void Test(TransactionTest test) { EthereumSigner ethereumSigner = new EthereumSigner(OlympicSpecProvider.Instance, NullLogManager.Instance); Transaction decodedUnsigned = Rlp.Decode <Transaction>(test.Unsigned); Assert.AreEqual(test.Value, decodedUnsigned.Value, "value"); Assert.AreEqual(test.GasPrice, decodedUnsigned.GasPrice, "gasPrice"); Assert.AreEqual(test.StartGas, decodedUnsigned.GasLimit, "gasLimit"); Assert.AreEqual(test.Data, decodedUnsigned.Data ?? decodedUnsigned.Init, "data"); Assert.AreEqual(test.To, decodedUnsigned.To, "to"); Assert.AreEqual(test.Nonce, decodedUnsigned.Nonce, "nonce"); Transaction decodedSigned = Rlp.Decode <Transaction>(test.Signed); ethereumSigner.Sign(test.PrivateKey, decodedUnsigned, 0); Assert.AreEqual(decodedSigned.Signature.R, decodedUnsigned.Signature.R, "R"); BigInteger expectedS = decodedSigned.Signature.S.ToUnsignedBigInteger(); BigInteger actualS = decodedUnsigned.Signature.S.ToUnsignedBigInteger(); BigInteger otherS = EthereumSigner.LowSTransform - actualS; // test does not use normalized signature if (otherS != expectedS && actualS != expectedS) { throw new Exception("S is wrong"); } int vToCompare = decodedUnsigned.Signature.V; if (otherS == decodedSigned.Signature.S.ToUnsignedBigInteger()) { vToCompare = vToCompare == 27 ? 28 : 27; } Assert.AreEqual(decodedSigned.Signature.V, vToCompare, "V"); }
public void Setup_chain() { // Import blocks _blockTree = Build.A.BlockTree().TestObject; Block genesisBlock = GetRinkebyGenesis(); Block block1 = Rlp.Decode <Block>(new Rlp(Bytes.FromHexString(Block1Rlp))); Block block2 = Rlp.Decode <Block>(new Rlp(Bytes.FromHexString(Block2Rlp))); Block block3 = Rlp.Decode <Block>(new Rlp(Bytes.FromHexString(Block3Rlp))); Block block4 = Rlp.Decode <Block>(new Rlp(Bytes.FromHexString(Block4Rlp))); Block block5 = Rlp.Decode <Block>(new Rlp(Bytes.FromHexString(Block5Rlp))); _lastBlock = block5; // Add blocks MineBlock(_blockTree, genesisBlock); MineBlock(_blockTree, block1); MineBlock(_blockTree, block2); MineBlock(_blockTree, block3); MineBlock(_blockTree, block4); MineBlock(_blockTree, block5); IEthereumSigner signer = new EthereumSigner(RinkebySpecProvider.Instance, NullLogManager.Instance); // Init snapshot db IDb db = new MemDb(); CliqueConfig config = new CliqueConfig(); // Select in-turn signer int currentBlock = 6; int currentSignerIndex = (currentBlock % _signers.Count); _currentSigner = _signers[currentSignerIndex]; _clique = new CliqueSealEngine(config, signer, _currentSigner, db, _blockTree, NullLogManager.Instance); }
public void Sign_and_recover() { EthereumSigner ethereumSigner = new EthereumSigner(OlympicSpecProvider.Instance, NullLogManager.Instance); Keccak message = Keccak.Compute("Test message"); PrivateKey privateKey = new PrivateKey(_cryptoRandom.GenerateRandomBytes(32)); Signature signature = ethereumSigner.Sign(privateKey, message); Assert.AreEqual(privateKey.Address, ethereumSigner.RecoverAddress(signature, message)); }
public void Sign_and_recover() { EthereumSigner ethereumSigner = new EthereumSigner(OlympicSpecProvider.Instance, NullLogManager.Instance); Keccak message = Keccak.Compute("Test message"); PrivateKey privateKey = Build.A.PrivateKey.TestObject; Signature signature = ethereumSigner.Sign(privateKey, message); Assert.AreEqual(privateKey.Address, ethereumSigner.RecoverAddress(signature, message)); }
public void Test_eip155_for_the_first_ropsten_transaction() { Transaction tx = Rlp.Decode <Transaction>(new Rlp(Bytes.FromHexString("0xf85f808082520894353535353535353535353535353535353535353580801ca08d24b906be2d91a0bf2168862726991cc408cddf94cb087b392ce992573be891a077964b4e55a5c8ec7b85087d619c641c06def33ab052331337ca9efcd6b82aef"))); Assert.AreEqual(new Keccak("0x5fd225549ed5c587c843e04578bdd4240fc0d7ab61f8e9faa37e84ec8dc8766d"), tx.Hash, "hash"); EthereumSigner signer = new EthereumSigner(RopstenSpecProvider.Instance, NullLogManager.Instance); Address from = signer.RecoverAddress(tx, 11); Assert.AreEqual(new Address("0x874b54a8bd152966d63f706bae1ffeb0411921e5"), from, "from"); }
public void should_ignore_transactions_with_different_chain_id() { _transactionPool = CreatePool(_noTransactionStorage); EthereumSigner signer = new EthereumSigner(MainNetSpecProvider.Instance, _logManager); Transaction tx = Build.A.Transaction.SignedAndResolved(signer, TestItem.PrivateKeyA, MainNetSpecProvider.ByzantiumBlockNumber).TestObject; AddTransactionResult result = _transactionPool.AddTransaction(tx, 1); _transactionPool.GetPendingTransactions().Length.Should().Be(0); result.Should().Be(AddTransactionResult.InvalidChainId); }
public void Signature_test_olympic(int blockNumber) { EthereumSigner signer = new EthereumSigner(OlympicSpecProvider.Instance, NullLogManager.Instance); PrivateKey key = Build.A.PrivateKey.TestObject; Transaction tx = Build.A.Transaction.TestObject; signer.Sign(key, tx, blockNumber); Address address = signer.RecoverAddress(tx, blockNumber); Assert.AreEqual(key.Address, address); }
public void Sign_goerli() { EthereumSigner signer = new EthereumSigner(GoerliSpecProvider.Instance, LimboLogs.Instance); PrivateKey key = Build.A.PrivateKey.TestObject; Transaction tx = Build.A.Transaction.TestObject; signer.Sign(key, tx, 1); Address address = signer.RecoverAddress(tx, 1); Assert.AreEqual(key.Address, address); }
public void Signature_test_ropsten(uint blockNumber) { EthereumSigner signer = new EthereumSigner(RopstenSpecProvider.Instance, LimboLogs.Instance); PrivateKey key = Build.A.PrivateKey.TestObject; Transaction tx = Build.A.Transaction.TestObject; signer.Sign(key, tx, blockNumber); Address address = signer.RecoverAddress(tx, blockNumber); Assert.AreEqual(key.Address, address); }
private void RunTest(TransactionTest test, IReleaseSpec spec) { //TestContext.CurrentContext.Test.Properties.Set("Category", test.Network); // no longer public ValidTransactionTest validTest = test as ValidTransactionTest; Nethermind.Core.Transaction transaction; try { Rlp rlp = new Rlp(Bytes.FromHexString(test.Rlp)); transaction = Rlp.Decode <Nethermind.Core.Transaction>(rlp); } catch (Exception) { if (validTest == null) { return; } throw; } bool useChainId = transaction.Signature.V > 28; SignatureValidator signatureValidator = new SignatureValidator(useChainId ? ChainId.MainNet : 0); TransactionValidator validator = new TransactionValidator(signatureValidator); if (validTest != null) { Assert.AreEqual(validTest.Value, transaction.Value, "value"); Assert.AreEqual(validTest.Data, transaction.Data ?? transaction.Init, "data"); Assert.AreEqual(validTest.GasLimit, transaction.GasLimit, "gasLimit"); Assert.AreEqual(validTest.GasPrice, transaction.GasPrice, "gasPrice"); Assert.AreEqual(validTest.Nonce, transaction.Nonce, "nonce"); Assert.AreEqual(validTest.To, transaction.To, "to"); Assert.True(validator.IsWellFormed(transaction, spec)); Signature expectedSignature = new Signature(validTest.R, validTest.S, validTest.V); Assert.AreEqual(expectedSignature, transaction.Signature, "signature"); // if(useChainId && spec.IsEip155Enabled) // IEthereumSigner signer = new EthereumSigner(new SingleReleaseSpecProvider(spec, useChainId ? (int)ChainId.MainNet : 0), NullLogManager.Instance); bool verified = signer.Verify( validTest.Sender, transaction, 0); Assert.True(verified); } else { Assert.False(validator.IsWellFormed(transaction, spec)); } }
public void Can_sign() { EthereumSigner signer = new EthereumSigner(new SingleReleaseSpecProvider(LatestRelease.Instance, 99), NullLogManager.Instance); DevWallet wallet = new DevWallet(NullLogManager.Instance); for (int i = 1; i <= 10; i++) { Address signerAddress = wallet.GetAccounts()[0]; Signature sig = wallet.Sign(signerAddress, TestObject.KeccakA); Address recovered = signer.RecoverAddress(sig, TestObject.KeccakA); Assert.AreEqual(signerAddress, recovered, $"{i}"); } }
public void Can_sign_on_networks_with_chain_id(DevWalletType walletType) { const int networkId = 40000; EthereumSigner signer = new EthereumSigner(new SingleReleaseSpecProvider(LatestRelease.Instance, networkId), NullLogManager.Instance); IWallet wallet = SetupWallet(walletType); for (int i = 1; i <= (walletType == DevWalletType.Memory ? 10 : 3); i++) { Address signerAddress = wallet.GetAccounts()[0]; Transaction tx = new Transaction(); tx.SenderAddress = signerAddress; wallet.Sign(tx, networkId); Address recovered = signer.RecoverAddress(tx, networkId); Assert.AreEqual(signerAddress, recovered, $"{i}"); Assert.AreEqual(networkId, tx.Signature.GetChainId, "chainId"); } }
public VirtualMachineTests() { _spec = RopstenSpecProvider.Instance; ILogManager logger = NullLogManager.Instance; IDb codeDb = new MemDb(); _stateDb = new SnapshotableDb(new MemDb()); StateTree stateTree = new StateTree(_stateDb); _stateProvider = new StateProvider(stateTree, codeDb, logger); _storageDbProvider = new MemDbProvider(logger); _storageProvider = new StorageProvider(_storageDbProvider, _stateProvider, logger); _ethereumSigner = new EthereumSigner(_spec, logger); IBlockhashProvider blockhashProvider = new TestBlockhashProvider(); IVirtualMachine virtualMachine = new VirtualMachine(_stateProvider, _storageProvider, blockhashProvider, logger); _processor = new TransactionProcessor(_spec, _stateProvider, _storageProvider, virtualMachine, this, logger); }
private ISealEngine ConfigureSealEngine(TransactionStore transactionStore, EthereumSigner ethereumSigner) { var blockMiningTime = TimeSpan.FromMilliseconds(_initConfig.FakeMiningDelay); // var sealEngine = new EthashSealEngine(new Ethash()); var sealEngine = new FakeSealEngine(blockMiningTime, false); sealEngine.IsMining = _initConfig.IsMining; if (sealEngine.IsMining) { var transactionDelay = TimeSpan.FromMilliseconds(_initConfig.FakeMiningDelay / 4); TestTransactionsGenerator testTransactionsGenerator = new TestTransactionsGenerator(transactionStore, ethereumSigner, transactionDelay, _logManager); // stateProvider.CreateAccount(testTransactionsGenerator.SenderAddress, 1000.Ether()); // stateProvider.Commit(specProvider.GenesisSpec); testTransactionsGenerator.Start(); } return(sealEngine); }
private static string SendEth(Address address, decimal amount) { UInt256 blockNumber = _client.Post <UInt256>("eth_blockNumber").Result; Transaction tx = new Transaction(); tx.Value = (UInt256)(amount * (decimal)1.Ether()); tx.To = address; tx.GasLimit = 21000; tx.GasPrice = (UInt256)(_engine.GetValue("gasPrice").AsNumber()); tx.Nonce = (ulong)_client.Post <BigInteger>("eth_getTransactionCount", _nodeKey.Address, blockNumber).Result; tx.SenderAddress = _nodeKey.Address; int chainId = _client.Post <int>("net_version").Result; EthereumSigner signer = new EthereumSigner(new SingleReleaseSpecProvider(ConstantinopleFix.Instance, chainId), _logManager); signer.Sign(_nodeKey, tx, blockNumber); Keccak keccak = _client.Post <Keccak>("eth_sendRawTransaction", Rlp.Encode(tx, false).Bytes).Result; return(_serializer.Serialize(keccak, true)); }
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"); }
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); IEthereumSigner signer = new EthereumSigner(specProvider, _logManager); ITransactionPool transactionPool = new TransactionPool(NullTransactionStorage.Instance, new PendingTransactionThresholdValidator(), new Timestamp(), signer, _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, SealEngine, 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(signer, 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"); }
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); }
protected async Task RunTest(BlockchainTest test, Stopwatch stopwatch = null) { LoggingTraceListener traceListener = new LoggingTraceListener(); // TODO: not supported in .NET Core, need to replace? // Debug.Listeners.Clear(); // Debug.Listeners.Add(traceListener); IDbProvider dbProvider = new MemDbProvider(_logManager); StateTree stateTree = new StateTree(dbProvider.GetOrCreateStateDb()); 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"); } IDifficultyCalculator difficultyCalculator = new DifficultyCalculator(specProvider); IRewardCalculator rewardCalculator = new RewardCalculator(specProvider); IBlockTree blockTree = new BlockTree(new MemDb(), new MemDb(), new MemDb(), specProvider, _logManager); IBlockhashProvider blockhashProvider = new BlockhashProvider(blockTree); ISignatureValidator signatureValidator = new SignatureValidator(ChainId.MainNet); ITransactionValidator transactionValidator = new TransactionValidator(signatureValidator); IHeaderValidator headerValidator = new HeaderValidator(difficultyCalculator, blockTree, SealEngine, specProvider, _logManager); IOmmersValidator ommersValidator = new OmmersValidator(blockTree, headerValidator, _logManager); IBlockValidator blockValidator = new BlockValidator(transactionValidator, headerValidator, ommersValidator, specProvider, _logManager); IStateProvider stateProvider = new StateProvider(stateTree, dbProvider.GetOrCreateCodeDb(), _logManager); IStorageProvider storageProvider = new StorageProvider(dbProvider, stateProvider, _logManager); IVirtualMachine virtualMachine = new VirtualMachine( stateProvider, storageProvider, blockhashProvider, _logManager); ISealEngine sealEngine = new EthashSealEngine(new Ethash(_logManager), _logManager); ITransactionStore transactionStore = new TransactionStore(); IEthereumSigner signer = new EthereumSigner(specProvider, _logManager); IBlockProcessor blockProcessor = new BlockProcessor( specProvider, blockValidator, rewardCalculator, new TransactionProcessor( specProvider, stateProvider, storageProvider, virtualMachine, NullTracer.Instance, _logManager), dbProvider, stateProvider, storageProvider, transactionStore, _logManager); IBlockchainProcessor blockchainProcessor = new BlockchainProcessor(blockTree, sealEngine, transactionStore, difficultyCalculator, blockProcessor, signer, _logManager); 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 = Hex.ToBytes(testBlockJson.Rlp).AsRlpContext(); Block suggestedBlock = Rlp.Decode <Block>(rlpContext); 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 e) { _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"); blockTree.NewHeadBlock += (sender, args) => { if (args.Block.Number == 0) { Assert.AreEqual(genesisBlock.Header.StateRoot, stateTree.RootHash, "genesis state root"); } }; blockchainProcessor.Start(); blockTree.SuggestBlock(genesisBlock); 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 (blockValidator.ValidateSuggestedBlock(correctRlpsBlocks[i].Block)) { blockTree.SuggestBlock(correctRlpsBlocks[i].Block); } else { Console.WriteLine("Invalid block"); } } catch (InvalidBlockException ex) { } catch (Exception ex) { _logger?.Info(ex.ToString()); } } await blockchainProcessor.StopAsync(true); stopwatch?.Stop(); RunAssertions(test, blockTree.RetrieveHeadBlock(), storageProvider, stateProvider); }
private async Task InitBlockchain(InitParams initParams) { ChainSpec chainSpec = LoadChainSpec(initParams.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, initParams); /* sync */ var blocksDb = new DbOnTheRocks(Path.Combine(_dbBasePath, DbOnTheRocks.BlocksDbPath)); var blockInfosDb = new DbOnTheRocks(Path.Combine(_dbBasePath, DbOnTheRocks.BlockInfosDbPath)); var receiptsDb = new DbOnTheRocks(Path.Combine(_dbBasePath, DbOnTheRocks.ReceiptsDbPath)); /* blockchain */ var 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); var codeDb = new DbOnTheRocks(Path.Combine(_dbBasePath, DbOnTheRocks.CodeDbPath)); var stateDb = new DbOnTheRocks(Path.Combine(_dbBasePath, DbOnTheRocks.StateDbPath)); var stateTree = new StateTree(stateDb); var stateProvider = new StateProvider(stateTree, codeDb, _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); // create shared objects between discovery and peer manager _nodeFactory = new NodeFactory(); _nodeStatsProvider = new NodeStatsProvider(_configProvider); 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(initParams.GenesisHash) ? null : new Keccak(initParams.GenesisHash), blockTree, stateProvider, specProvider); await StartProcessing(blockTree, transactionStore, blockValidator, headerValidator, txValidator, initParams); }
protected void RunTest(BlockchainTest test, Stopwatch stopwatch = null) { LoggingTraceListener traceListener = new LoggingTraceListener(_logger); // TODO: not supported in .NET Core, need to replace? // Debug.Listeners.Clear(); // Debug.Listeners.Add(traceListener); InitializeTestState(test); // TODO: transition... _stateProviders[test.Network].EthereumRelease = _protocolSpecificationProvider.GetSpec(test.Network, 0); IEthereumRelease spec = _protocolSpecificationProvider.GetSpec(test.Network, 1); IEthereumSigner signer = new EthereumSigner(spec, ChainId.MainNet); IBlockProcessor blockProcessor = new BlockProcessor( spec, _chain, _blockValidators[test.Network], new ProtocolBasedDifficultyCalculator(spec), new RewardCalculator(spec), new TransactionProcessor( spec, _stateProviders[test.Network], _storageProviders[test.Network], _virtualMachines[test.Network], signer, ShouldLog.Processing ? _logger : null), _multiDb, _stateProviders[test.Network], _storageProviders[test.Network], new TransactionStore(), ShouldLog.Processing ? _logger : null); IBlockchainProcessor blockchainProcessor = new BlockchainProcessor( test.GenesisRlp, blockProcessor, _chain, ShouldLog.Processing ? _logger : null); var rlps = test.Blocks.Select(tb => new Rlp(Hex.ToBytes(tb.Rlp))).ToArray(); for (int i = 0; i < rlps.Length; i++) { stopwatch?.Start(); try { blockchainProcessor.Process(rlps[i]); } catch (InvalidBlockException ex) { } catch (Exception ex) { _logger?.Log(ex.ToString()); } stopwatch?.Stop(); } RunAssertions(test, blockchainProcessor.HeadBlock); }
private static void InitBlockchain(ChainSpec chainSpec, bool isMining, int miningDelay) { /* spec */ var blockMiningTime = TimeSpan.FromMilliseconds(miningDelay); var transactionDelay = TimeSpan.FromMilliseconds(miningDelay / 4); var specProvider = RopstenSpecProvider.Instance; var difficultyCalculator = new DifficultyCalculator(specProvider); // var sealEngine = new EthashSealEngine(new Ethash()); var sealEngine = new FakeSealEngine(blockMiningTime, false); /* sync */ var transactionStore = new TransactionStore(); var blockTree = new BlockTree(RopstenSpecProvider.Instance, ChainLogger); /* validation */ var headerValidator = new HeaderValidator(difficultyCalculator, blockTree, sealEngine, specProvider, ChainLogger); var ommersValidator = new OmmersValidator(blockTree, headerValidator, ChainLogger); var txValidator = new TransactionValidator(new SignatureValidator(ChainId.Ropsten)); var blockValidator = new BlockValidator(txValidator, headerValidator, ommersValidator, specProvider, ChainLogger); /* state */ var dbProvider = new DbProvider(StateLogger); var codeDb = new InMemoryDb(); var stateDb = new InMemoryDb(); var stateTree = new StateTree(stateDb); var stateProvider = new StateProvider(stateTree, StateLogger, codeDb); var storageProvider = new StorageProvider(dbProvider, stateProvider, StateLogger); var storageDbProvider = new DbProvider(StateLogger); /* blockchain */ var ethereumSigner = new EthereumSigner(specProvider, ChainLogger); /* blockchain processing */ var blockhashProvider = new BlockhashProvider(blockTree); var virtualMachine = new VirtualMachine(specProvider, stateProvider, storageProvider, blockhashProvider, EvmLogger); var transactionProcessor = new TransactionProcessor(specProvider, stateProvider, storageProvider, virtualMachine, ethereumSigner, ChainLogger); var rewardCalculator = new RewardCalculator(specProvider); var blockProcessor = new BlockProcessor(specProvider, blockValidator, rewardCalculator, transactionProcessor, storageDbProvider, stateProvider, storageProvider, transactionStore, ChainLogger); _blockchainProcessor = new BlockchainProcessor(blockTree, sealEngine, transactionStore, difficultyCalculator, blockProcessor, ChainLogger); /* genesis */ foreach (KeyValuePair <Address, BigInteger> allocation in chainSpec.Allocations) { stateProvider.CreateAccount(allocation.Key, allocation.Value); } stateProvider.Commit(specProvider.GenesisSpec); var testTransactionsGenerator = new TestTransactionsGenerator(transactionStore, ethereumSigner, transactionDelay, ChainLogger); stateProvider.CreateAccount(testTransactionsGenerator.SenderAddress, 1000.Ether()); stateProvider.Commit(specProvider.GenesisSpec); if (isMining) { testTransactionsGenerator.Start(); } Block genesis = chainSpec.Genesis; genesis.Header.StateRoot = stateProvider.StateRoot; genesis.Header.RecomputeHash(); // we are adding test transactions account so the state root will change (not an actual ropsten at the moment) // var expectedGenesisHash = "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d"; // if (chainSpec.Genesis.Hash != new Keccak(expectedGenesisHash)) // { // throw new Exception($"Unexpected genesis hash for Ropsten, expected {expectedGenesisHash}, but was {chainSpec.Genesis.Hash}"); // } /* start test processing */ sealEngine.IsMining = isMining; _blockchainProcessor.Start(); blockTree.AddBlock(genesis); _syncManager = new SynchronizationManager( blockTree, blockValidator, headerValidator, transactionStore, txValidator, NetworkLogger); _syncManager.Start(); }
public On CreateNode(PrivateKey privateKey, bool withGenesisAlreadyProcessed = false) { AutoResetEvent newHeadBlockEvent = new AutoResetEvent(false); _blockEvents.Add(privateKey, newHeadBlockEvent); MemDb blocksDb = new MemDb(); MemDb blockInfoDb = new MemDb(); TransactionPool transactionPool = new TransactionPool(new InMemoryTransactionStorage(), new PendingTransactionThresholdValidator(), _timestamp, _ethereumSigner, GoerliSpecProvider.Instance, NullLogManager.Instance); _pools[privateKey] = transactionPool; BlockTree blockTree = new BlockTree(blocksDb, blockInfoDb, GoerliSpecProvider.Instance, transactionPool, NullLogManager.Instance); blockTree.NewHeadBlock += (sender, args) => { _blockEvents[privateKey].Set(); }; BlockhashProvider blockhashProvider = new BlockhashProvider(blockTree); _blockTrees.Add(privateKey, blockTree); EthereumSigner ethereumSigner = new EthereumSigner(GoerliSpecProvider.Instance, NullLogManager.Instance); CliqueSealEngine cliqueSealEngine = new CliqueSealEngine(_cliqueConfig, ethereumSigner, privateKey, new MemDb(), blockTree, NullLogManager.Instance); cliqueSealEngine.CanSeal = true; ISnapshotableDb stateDb = new StateDb(); ISnapshotableDb codeDb = new StateDb(); IDb traceDb = new MemDb(); StateProvider stateProvider = new StateProvider(new StateTree(stateDb), codeDb, NullLogManager.Instance); stateProvider.CreateAccount(TestObject.PrivateKeyD.Address, 100.Ether()); stateProvider.Commit(GoerliSpecProvider.Instance.GenesisSpec); _genesis.StateRoot = _genesis3Validators.StateRoot = stateProvider.StateRoot; _genesis.Hash = BlockHeader.CalculateHash(_genesis.Header); _genesis3Validators.Hash = BlockHeader.CalculateHash(_genesis3Validators.Header); StorageProvider storageProvider = new StorageProvider(stateDb, stateProvider, NullLogManager.Instance); TransactionProcessor transactionProcessor = new TransactionProcessor(GoerliSpecProvider.Instance, stateProvider, storageProvider, new VirtualMachine(stateProvider, storageProvider, blockhashProvider, NullLogManager.Instance), NullLogManager.Instance); BlockProcessor blockProcessor = new BlockProcessor(GoerliSpecProvider.Instance, TestBlockValidator.AlwaysValid, new NoBlockRewards(), transactionProcessor, stateDb, codeDb, traceDb, stateProvider, storageProvider, transactionPool, NullReceiptStorage.Instance, NullLogManager.Instance); BlockchainProcessor processor = new BlockchainProcessor(blockTree, blockProcessor, new AuthorRecoveryStep(cliqueSealEngine), NullLogManager.Instance, false, false); processor.Start(); StateProvider minerStateProvider = new StateProvider(new StateTree(stateDb), codeDb, NullLogManager.Instance); StorageProvider minerStorageProvider = new StorageProvider(stateDb, minerStateProvider, NullLogManager.Instance); VirtualMachine minerVirtualMachine = new VirtualMachine(minerStateProvider, minerStorageProvider, blockhashProvider, NullLogManager.Instance); TransactionProcessor minerTransactionProcessor = new TransactionProcessor(GoerliSpecProvider.Instance, minerStateProvider, minerStorageProvider, minerVirtualMachine, NullLogManager.Instance); BlockProcessor minerBlockProcessor = new BlockProcessor(GoerliSpecProvider.Instance, TestBlockValidator.AlwaysValid, new NoBlockRewards(), minerTransactionProcessor, stateDb, codeDb, traceDb, minerStateProvider, minerStorageProvider, transactionPool, NullReceiptStorage.Instance, NullLogManager.Instance); BlockchainProcessor minerProcessor = new BlockchainProcessor(blockTree, minerBlockProcessor, new AuthorRecoveryStep(cliqueSealEngine), NullLogManager.Instance, false, false); if (withGenesisAlreadyProcessed) { ProcessGenesis(privateKey); } CliqueBlockProducer blockProducer = new CliqueBlockProducer(transactionPool, minerProcessor, blockTree, minerStateProvider, _timestamp, new CryptoRandom(), cliqueSealEngine, _cliqueConfig, privateKey.Address, NullLogManager.Instance); blockProducer.Start(); _producers.Add(privateKey, blockProducer); return(this); }
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 */ FakeSealEngine sealEngine = new FakeSealEngine(miningDelay); sealEngine.CanSeal = true; RopstenSpecProvider specProvider = RopstenSpecProvider.Instance; /* store & validation */ EthereumSigner ethereumSigner = new EthereumSigner(specProvider, logManager); MemDb receiptsDb = new MemDb(); MemDb traceDb = new MemDb(); TransactionPool transactionPool = new TransactionPool(new NullTransactionStorage(), new PendingTransactionThresholdValidator(), new Timestamp(), ethereumSigner, 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, sealEngine, 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, ethereumSigner, 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(ethereumSigner, NullTransactionPool.Instance), logManager, false, false); /* load ChainSpec and init */ ChainSpecLoader loader = new ChainSpecLoader(new UnforgivingJsonSerializer()); 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, sealEngine, blockTree, timestamp, NullLogManager.Instance); minedBlockProducer.Start(); ManualResetEvent manualResetEvent = new ManualResetEvent(false); blockTree.NewHeadBlock += (sender, args) => { if (args.Block.Number == 6) { manualResetEvent.Set(); } }; manualResetEvent.WaitOne(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"); ManualResetEvent blockProcessedEvent = new ManualResetEvent(false); blockchainProcessor.ProcessingQueueEmpty += (sender, args) => blockProcessedEvent.Set(); blockchainProcessor.SuggestBlock(block.Hash, ProcessingOptions.ForceProcessing | ProcessingOptions.StoreReceipts | ProcessingOptions.ReadOnlyChain); blockProcessedEvent.WaitOne(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"); }
public void Encode_decode_with_eip155(int chainId) { EthereumSigner signer = new EthereumSigner(OlympicSpecProvider.Instance, NullLogManager.Instance); TestEncodeDecode(signer); }
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); }); }