public void Fill() { IEnumerable <Transaction> mem_pool = blockchain.GetVerifiedTransactions(); foreach (IPolicyPlugin plugin in PluginManager.Singleton.Policies) { mem_pool = plugin.FilterForBlock(mem_pool); } List <Transaction> transactions = mem_pool.ToList(); while (true) { ulong nonce = Transaction.GetNonce(); MinerTransaction tx = new MinerTransaction { ChainHash = blockchain.ChainHash, Nonce = nonce, Account = wallet.GetChangeAddress(), Attributes = new TransactionAttribute[0], Witnesses = new Witness[0] }; if (!snapshot.ContainsTransaction(tx.Hash)) { Nonce = nonce; transactions.Insert(0, tx); break; } } TransactionHashes = transactions.Select(p => p.Hash).ToArray(); Transactions = transactions.ToDictionary(p => p.Hash); NextConsensus = Blockchain.GetConsensusAddress(snapshot.GetValidators(transactions).ToArray()); Timestamp = Math.Max(TimeProvider.Current.UtcNow.ToTimestamp(), PrevHeader.Timestamp + 1); }
public async Task Persist_MinerTx_NoSpecialCalls() { var input = new MinerTransaction(); var testee = AutoMockContainer.Create <TransactionPersister>(); await testee.Persist(input); }
public void SerializeDeserialize_MinerTransaction() { var original = new MinerTransaction() { Version = 0x00, Nonce = (uint)_random.Next(0, int.MaxValue) }; FillRandomTx(original); var ret = _serializer.Serialize(original); var copy = _deserializer.Deserialize <Transaction>(ret); var copy2 = _deserializer.Deserialize <MinerTransaction>(ret); // Check exclusive data foreach (var check in new MinerTransaction[] { (MinerTransaction)copy, copy2 }) { Assert.AreEqual(original.Nonce, check.Nonce); } // Check base data EqualTx(original, copy, copy2); }
/* * private void FillContext() * { * IEnumerable<Transaction> mem_pool = Blockchain.Singleton.GetMemoryPool(); * foreach (IPolicyPlugin plugin in Plugin.Policies) * mem_pool = plugin.FilterForBlock(mem_pool); * List<Transaction> transactions = mem_pool.ToList(); * Fixed8 amount_netfee = Block.CalculateNetFee(transactions); * TransactionOutput[] outputs = amount_netfee == Fixed8.Zero ? new TransactionOutput[0] : new[] { new TransactionOutput * { * AssetId = Blockchain.UtilityToken.Hash, * Value = amount_netfee, * ScriptHash = wallet.GetChangeAddress() * } }; * while (true) * { * ulong nonce = GetNonce(); * MinerTransaction tx = new MinerTransaction * { * Nonce = (uint)(nonce % (uint.MaxValue + 1ul)), * Attributes = new TransactionAttribute[0], * Inputs = new CoinReference[0], * Outputs = outputs, * Witnesses = new Witness[0] * }; * if (!context.Snapshot.ContainsTransaction(tx.Hash)) * { * context.Nonce = nonce; * transactions.Insert(0, tx); * break; * } * } * context.TransactionHashes = transactions.Select(p => p.Hash).ToArray(); * context.Transactions = transactions.ToDictionary(p => p.Hash); * context.NextConsensus = Blockchain.GetConsensusAddress(context.Snapshot.GetValidators(transactions).ToArray()); * } */ /// <summary> /// 添加挖矿产出 /// </summary> private void FillContext() { IEnumerable <Transaction> mem_pool = Blockchain.Singleton.GetMemoryPool(); foreach (IPolicyPlugin plugin in Plugin.Policies) { mem_pool = plugin.FilterForBlock(mem_pool); } List <Transaction> transactions = mem_pool.ToList(); Fixed8 amount_netfee = Block.CalculateNetFee(transactions); MiningTransaction miningTransaction = new MiningTransaction(amount_netfee); while (true) { ulong nonce = GetNonce(); MinerTransaction tx = miningTransaction.GetMinerTransaction(nonce, context.BlockIndex, wallet); if (!context.Snapshot.ContainsTransaction(tx.Hash)) { context.Nonce = nonce; transactions.Insert(0, tx); break; } } context.TransactionHashes = transactions.Select(p => p.Hash).ToArray(); context.Transactions = transactions.ToDictionary(p => p.Hash); context.NextConsensus = Blockchain.GetConsensusAddress(context.Snapshot.GetValidators(transactions).ToArray()); }
public async Task Process_MinerTx_NoSpecialCalls() { var input = new MinerTransaction(); var testee = AutoMockContainer.Create <TransactionProcessor>(); await testee.Process(input); }
/// <summary> /// The first miner transaction /// </summary> /// <returns>The miner transaction.</returns> public static MinerTransaction GenesisMinerTransaction() { uint genesisMinerNonce = 2083236893; var genesisMinerTransaction = new MinerTransaction { Nonce = genesisMinerNonce, Attributes = new TransactionAttribute[0], Inputs = new CoinReference[0], Outputs = new TransactionOutput[0], Witness = new Witness[0] }; return(genesisMinerTransaction); }
public MinerTransaction GetMinerTransaction(ulong nonce, uint blockIndex, Wallet wallet) { if (blockIndex < 1) { return(new MinerTransaction { Nonce = (uint)(nonce % (uint.MaxValue + 1ul)), Attributes = new TransactionAttribute[0], Inputs = new CoinReference[0], Outputs = amount_netfee == Fixed8.Zero ? new TransactionOutput[0] : new TransactionOutput[] { NetFeeOutput(wallet, amount_netfee) }, Witnesses = new Witness[0] }); } if (outputs == null) { MakeTransactionOutputs(blockIndex, wallet, amount_netfee); byte[] hashDataOfMining = GetHashData(); if (hashDataOfMining != null) { //Signature WalletAccount account = wallet.GetAccount(wallet.GetChangeAddress()); if (account?.HasKey == true) { KeyPair key = account.GetKey(); signatureOfMining = Crypto.Default.Sign(hashDataOfMining, key.PrivateKey, key.PublicKey.EncodePoint(false).Skip(1).ToArray()); } } } MinerTransaction tx = new MinerTransaction { Nonce = (uint)(nonce % (uint.MaxValue + 1ul)), Attributes = signatureOfMining == null ? new TransactionAttribute[0] : new TransactionAttribute[] { new TransactionAttribute { Usage = TransactionAttributeUsage.Description, Data = signatureOfMining } }, Inputs = new CoinReference[0], Outputs = outputs, Witnesses = new Witness[0] }; return(tx); }
public override void Deserialize(BinaryReader reader) { base.Deserialize(reader); Nonce = reader.ReadUInt64(); TransactionHashes = reader.ReadSerializableArray <UInt256>(); if (TransactionHashes.Distinct().Count() != TransactionHashes.Length) { throw new FormatException(); } MinerTransaction = reader.ReadSerializable <MinerTransaction>(); if (MinerTransaction.Hash != TransactionHashes[0]) { throw new FormatException(); } Signature = reader.ReadBytes(64); }
public override void Deserialize(BinaryReader reader) { base.Deserialize(reader); Timestamp = reader.ReadUInt32(); Nonce = reader.ReadUInt64(); NextConsensus = reader.ReadSerializable <UInt160>(); TransactionHashes = reader.ReadSerializableArray <UInt256>(Block.MaxTransactionsPerBlock); if (TransactionHashes.Distinct().Count() != TransactionHashes.Length) { throw new FormatException(); } MinerTransaction = reader.ReadSerializable <MinerTransaction>(); if (MinerTransaction.Hash != TransactionHashes[0]) { throw new FormatException(); } }
private void FillContext() { ReportNeoBlockchain reportObj = new ReportNeoBlockchain("[NeoConsensusService-FillContext]"); List <Transaction> transactions = LocalNode.GetMemoryPool().Where(p => CheckPolicy(p)).ToList(); if (transactions.Count >= Settings.Default.MaxTransactionsPerBlock) { transactions = transactions.OrderByDescending(p => p.NetworkFee / p.Size).Take(Settings.Default.MaxTransactionsPerBlock - 1).ToList(); } Fixed8 amount_netfee = Block.CalculateNetFee(transactions); TransactionOutput[] outputs = amount_netfee == Fixed8.Zero ? new TransactionOutput[0] : new[] { new TransactionOutput { AssetId = Blockchain.UtilityToken.Hash, Value = amount_netfee, ScriptHash = wallet.GetChangeAddress() } }; while (true) { ulong nonce = GetNonce(); MinerTransaction tx = new MinerTransaction { Nonce = (uint)(nonce % (uint.MaxValue + 1ul)), Attributes = new TransactionAttribute[0], Inputs = new CoinReference[0], Outputs = outputs, Scripts = new Witness[0] }; if (Blockchain.Default.GetTransaction(tx.Hash) == null) { context.Nonce = nonce; transactions.Insert(0, tx); break; } } context.TransactionHashes = transactions.Select(p => p.Hash).ToArray(); context.Transactions = transactions.ToDictionary(p => p.Hash); context.NextConsensus = Blockchain.GetConsensusAddress(Blockchain.Default.GetValidators(transactions).ToArray()); reportObj.appendElapsedTime(); }
private void FillContext() { TR.Enter(); IEnumerable <Transaction> mem_pool = LocalNode.GetMemoryPool().Where(p => CheckPolicy(p)); foreach (PolicyPlugin plugin in PolicyPlugin.Instances) { mem_pool = plugin.Filter(mem_pool); } List <Transaction> transactions = mem_pool.ToList(); Fixed8 amount_netfee = Block.CalculateNetFee(transactions); TransactionOutput[] outputs = amount_netfee == Fixed8.Zero ? new TransactionOutput[0] : new[] { new TransactionOutput { AssetId = Blockchain.UtilityToken.Hash, Value = amount_netfee, ScriptHash = wallet.GetChangeAddress() } }; while (true) { ulong nonce = GetNonce(); MinerTransaction tx = new MinerTransaction { Nonce = (uint)(nonce % (uint.MaxValue + 1ul)), Attributes = new TransactionAttribute[0], Inputs = new CoinReference[0], Outputs = outputs, Scripts = new Witness[0] }; if (Blockchain.Default.GetTransaction(tx.Hash) == null) { context.Nonce = nonce; transactions.Insert(0, tx); break; } } context.TransactionHashes = transactions.Select(p => p.Hash).ToArray(); context.Transactions = transactions.ToDictionary(p => p.Hash); context.NextConsensus = Blockchain.GetConsensusAddress(Blockchain.Default.GetValidators(transactions).ToArray()); TR.Exit(); }
public override void Deserialize(BinaryReader reader) { ReportNeoBlockchain reportObj = new ReportNeoBlockchain("[NeoPrepareRequest-Deserialize]"); base.Deserialize(reader); Nonce = reader.ReadUInt64(); NextConsensus = reader.ReadSerializable <UInt160>(); TransactionHashes = reader.ReadSerializableArray <UInt256>(); if (TransactionHashes.Distinct().Count() != TransactionHashes.Length) { throw new FormatException(); } MinerTransaction = reader.ReadSerializable <MinerTransaction>(); if (MinerTransaction.Hash != TransactionHashes[0]) { throw new FormatException(); } Signature = reader.ReadBytes(64); reportObj.appendElapsedTime(); }
public void Fill() { IEnumerable <Transaction> mem_pool = Blockchain.Singleton.GetMemoryPool(); foreach (IPolicyPlugin plugin in Plugin.Policies) { mem_pool = plugin.FilterForBlock(mem_pool); } List <Transaction> transactions = mem_pool.ToList(); Fixed8 amount_netfee = Block.CalculateNetFee(transactions); TransactionOutput[] outputs = amount_netfee == Fixed8.Zero ? new TransactionOutput[0] : new[] { new TransactionOutput { AssetId = Blockchain.UtilityToken.Hash, Value = amount_netfee, ScriptHash = wallet.GetChangeAddress() } }; while (true) { ulong nonce = GetNonce(); MinerTransaction tx = new MinerTransaction { Nonce = (uint)(nonce % (uint.MaxValue + 1ul)), Attributes = new TransactionAttribute[0], Inputs = new CoinReference[0], Outputs = outputs, Witnesses = new Witness[0] }; if (!snapshot.ContainsTransaction(tx.Hash)) { Nonce = nonce; transactions.Insert(0, tx); break; } } TransactionHashes = transactions.Select(p => p.Hash).ToArray(); Transactions = transactions.ToDictionary(p => p.Hash); NextConsensus = Blockchain.GetConsensusAddress(snapshot.GetValidators(transactions).ToArray()); Timestamp = Math.Max(TimeProvider.Current.UtcNow.ToTimestamp(), PrevHeader.Timestamp + 1); }
private void FillContext() { IEnumerable <Transaction> mem_pool = blockchain.GetMemoryPool(); foreach (IPolicyPlugin plugin in system.PluginMgr.Policies) { mem_pool = plugin.FilterForBlock(mem_pool); } List <Transaction> transactions = mem_pool.ToList(); Fixed8 amount_netfee = Block.CalculateNetFee(transactions); TransactionOutput[] outputs = amount_netfee == Fixed8.Zero ? new TransactionOutput[0] : new[] { new TransactionOutput { AssetId = Blockchain.UtilityToken.Hash, Value = amount_netfee, ScriptHash = wallet.GetChangeAddress() } }; while (true) { ulong nonce = GetNonce(); MinerTransaction tx = new MinerTransaction { ChainHash = chainHash, Nonce = (uint)(nonce % (uint.MaxValue + 1ul)), Attributes = new TransactionAttribute[0], Inputs = new CoinReference[0], Outputs = outputs, Witnesses = new Witness[0] }; if (!context.Snapshot.ContainsTransaction(tx.Hash)) { context.Nonce = nonce; transactions.Insert(0, tx); break; } } context.TransactionHashes = transactions.Select(p => p.Hash).ToArray(); context.Transactions = transactions.ToDictionary(p => p.Hash); context.NextConsensus = Blockchain.GetConsensusAddress(context.Snapshot.GetValidators(transactions).ToArray()); }
public MinerTransaction MakeMinerTransaction(Wallet wallet, uint blockIndex, ulong nonce, Fixed8 amount_txfee, Fixed8 amount_netfee) { List <TransactionOutput> outputs = new List <TransactionOutput>(); List <TransactionAttribute> attributes = new List <TransactionAttribute>(); if (blockIndex > 0) { AddMiningTransaction(wallet, blockIndex, outputs, attributes); AddTxFee(outputs, amount_txfee, blockIndex); AddNetFee(wallet, outputs, amount_netfee); } MinerTransaction tx = new MinerTransaction { Nonce = (uint)(nonce % (uint.MaxValue + 1ul)), Attributes = attributes.ToArray(), Inputs = new CoinReference[0], Outputs = outputs.ToArray(), Witnesses = new Witness[0] }; return(tx); }
static void Mining(BhpSystem system) { Fixed8 amount_netfee = Fixed8.Zero; Fixed8 transaction_fee = Fixed8.Zero; ulong nonce = 100156895; BRC6Wallet wallet = new BRC6Wallet(new Bhp.Wallets.WalletIndexer(@"walletindex"), @"D:\BHP\Test\t1.json"); wallet.Unlock("1"); wallet.WalletTransaction += Wallet_WalletTransaction; MiningTransaction miningTransaction = new MiningTransaction(); MinerTransaction tx = miningTransaction.MakeMinerTransaction(wallet, 1000, nonce, Fixed8.Zero, Fixed8.Zero); Console.WriteLine(tx.ToJson()); Console.WriteLine("\n Staring Sign......"); ContractParametersContext context = new ContractParametersContext(tx); wallet.Sign(context); if (context.Completed) { Console.WriteLine("\n Sign successfully."); context.Verifiable.Witnesses = context.GetWitnesses(); string hexString = GetTxHashData(context.Verifiable).ToHexString(); Console.WriteLine($"\n {hexString}"); system.LocalNode.Tell(new LocalNode.Relay { Inventory = tx }); RelayResultReason reason = system.Blockchain.Ask <RelayResultReason>(tx).Result; Console.WriteLine("\n relay tx: " + reason); } Console.ReadLine(); }
public static Transaction CreateMinnerTransaction(SignDelegate2 sign) { // d55ccd8b368aca2402003f39549ad7b75385c226009b3080e0d886959b75b5ce TransactionOutput[] outputs = new TransactionOutput[] { new TransactionOutput { AssetId = Blockchain.GoverningToken.Hash, Value = Fixed8.FromDecimal(444), ScriptHash = currentAddress.ToScriptHash() } }; ulong nonce = GetNonce(); MinerTransaction tx = new MinerTransaction { Nonce = (uint)(nonce % (uint.MaxValue + 1ul)), Attributes = new TransactionAttribute[0], Inputs = new CoinReference[0], Outputs = outputs, Witnesses = new Witness[0] }; return(sign.Invoke(tx)); }
public void TestSetup() { uut = new MinerTransaction(); }
// Since ConensusContext's constructor is internal, it can't be used from neo-express. // CreatePreloadBlock replicates the following logic for creating an empty block with ConensusContext // var ctx = new Neo.Consensus.ConsensusContext(wallet, store); // ctx.Reset(0); // ctx.MakePrepareRequest(); // ctx.MakeCommit(); // ctx.Save(); // Block block = ctx.CreateBlock(); static Block CreatePreloadBlock(Neo.Wallets.Wallet wallet, Random random, Transaction?transaction = null) { using var snapshot = Blockchain.Singleton.GetSnapshot(); var validators = snapshot.GetValidators(); if (validators.Length != 1) { throw new InvalidOperationException("Preload only supported for single-node blockchains"); } var amountNetFee = Block.CalculateNetFee(Enumerable.Empty <Transaction>()); if (amountNetFee != Fixed8.Zero) { throw new InvalidOperationException("amountNetFee must be zero"); } var keyPair = wallet.GetAccount(validators[0]).GetKey(); var prevHash = snapshot.CurrentBlockHash; var prevBlock = snapshot.GetBlock(prevHash); var nonce = NextNonce(random); var minerTx = new MinerTransaction { Nonce = (uint)(nonce % (uint.MaxValue + 1ul)), Attributes = Array.Empty <TransactionAttribute>(), Inputs = Array.Empty <CoinReference>(), Outputs = Array.Empty <TransactionOutput>(), Witnesses = Array.Empty <Witness>() }; var blockTransactions = transaction == null ? new Transaction[] { minerTx } : new Transaction[] { minerTx, transaction }; var txHashes = blockTransactions.Select(tx => tx.Hash).ToArray(); var merkleRoot = MerkleTree.ComputeRoot(txHashes); var nextConsensus = Blockchain.GetConsensusAddress(snapshot.GetValidators(blockTransactions).ToArray()); var consensusData = nonce; var block = new Block() { Version = 0, PrevHash = prevHash, MerkleRoot = merkleRoot, Timestamp = prevBlock.Timestamp + 1, Index = prevBlock.Index + 1, ConsensusData = nonce, NextConsensus = nextConsensus, Transactions = Array.Empty <Transaction>(), }; var commit = new Neo.Consensus.Commit() { ViewNumber = 0, Signature = block.Sign(keyPair) }; var payload = new ConsensusPayload { Version = 0, PrevHash = prevHash, BlockIndex = block.Index, ValidatorIndex = (ushort)0, Data = Neo.IO.Helper.ToArray(commit) }; { var sc = new ContractParametersContext(payload); wallet.Sign(sc); payload.Witness = sc.GetWitnesses()[0]; } { var m = validators.Length - ((validators.Length - 1) / 3); Contract contract = Contract.CreateMultiSigContract(m, validators); ContractParametersContext sc = new ContractParametersContext(block); for (int i = 0, j = 0; i < validators.Length && j < m; i++) { sc.AddSignature(contract, validators[0], payload.GetDeserializedMessage <Neo.Consensus.Commit>().Signature); j++; } block.Witness = sc.GetWitnesses()[0]; block.Transactions = blockTransactions; } return(block); }
public void ConsensusService_Primary_Sends_PrepareRequest_After_OnStart() { TestProbe subscriber = CreateTestProbe(); var mockConsensusContext = new Mock <IConsensusContext>(); var mockStore = new Mock <Store>(); // context.Reset(): do nothing //mockConsensusContext.Setup(mr => mr.Reset()).Verifiable(); // void mockConsensusContext.SetupGet(mr => mr.MyIndex).Returns(2); // MyIndex == 2 mockConsensusContext.SetupGet(mr => mr.BlockIndex).Returns(2); mockConsensusContext.SetupGet(mr => mr.PrimaryIndex).Returns(2); mockConsensusContext.SetupGet(mr => mr.ViewNumber).Returns(0); mockConsensusContext.SetupProperty(mr => mr.Nonce); mockConsensusContext.SetupProperty(mr => mr.NextConsensus); mockConsensusContext.Object.NextConsensus = UInt160.Zero; mockConsensusContext.SetupGet(mr => mr.PreparationPayloads).Returns(new ConsensusPayload[7]); mockConsensusContext.SetupGet(mr => mr.CommitPayloads).Returns(new ConsensusPayload[7]); int timeIndex = 0; var timeValues = new[] { //new DateTime(1968, 06, 01, 0, 0, 15, DateTimeKind.Utc), // For tests here new DateTime(1968, 06, 01, 0, 0, 1, DateTimeKind.Utc), // For receiving block new DateTime(1968, 06, 01, 0, 0, (int)Blockchain.SecondsPerBlock, DateTimeKind.Utc), // For Initialize new DateTime(1968, 06, 01, 0, 0, 15, DateTimeKind.Utc), // unused new DateTime(1968, 06, 01, 0, 0, 15, DateTimeKind.Utc) // unused }; //TimeProvider.Current.UtcNow.ToTimestamp().Should().Be(4244941711); //1968-06-01 00:00:15 Console.WriteLine($"time 0: {timeValues[0].ToString()} 1: {timeValues[1].ToString()} 2: {timeValues[2].ToString()} 3: {timeValues[3].ToString()}"); //mockConsensusContext.Object.block_received_time = new DateTime(1968, 06, 01, 0, 0, 1, DateTimeKind.Utc); //mockConsensusContext.Setup(mr => mr.GetUtcNow()).Returns(new DateTime(1968, 06, 01, 0, 0, 15, DateTimeKind.Utc)); var timeMock = new Mock <TimeProvider>(); timeMock.SetupGet(tp => tp.UtcNow).Returns(() => timeValues[timeIndex]) .Callback(() => timeIndex++); //new DateTime(1968, 06, 01, 0, 0, 15, DateTimeKind.Utc)); TimeProvider.Current = timeMock.Object; //public void Log(string message, LogLevel level) // TODO: create ILogPlugin for Tests /* * mockConsensusContext.Setup(mr => mr.Log(It.IsAny<string>(), It.IsAny<LogLevel>())) * .Callback((string message, LogLevel level) => { * Console.WriteLine($"CONSENSUS LOG: {message}"); * } * ); */ // Creating proposed block Header header = new Header(); TestUtils.SetupHeaderWithValues(header, UInt256.Zero, out UInt256 merkRootVal, out UInt160 val160, out uint timestampVal, out uint indexVal, out ulong consensusDataVal, out Witness scriptVal); header.Size.Should().Be(109); Console.WriteLine($"header {header} hash {header.Hash} timstamp {timestampVal}"); timestampVal.Should().Be(4244941696); //1968-06-01 00:00:00 // check basic ConsensusContext mockConsensusContext.Object.MyIndex.Should().Be(2); //mockConsensusContext.Object.block_received_time.ToTimestamp().Should().Be(4244941697); //1968-06-01 00:00:01 MinerTransaction minerTx = new MinerTransaction { Attributes = new TransactionAttribute[0], Inputs = new CoinReference[0], Outputs = new TransactionOutput[0], Witnesses = new Witness[0], Nonce = 42 }; PrepareRequest prep = new PrepareRequest { Nonce = mockConsensusContext.Object.Nonce, NextConsensus = mockConsensusContext.Object.NextConsensus, TransactionHashes = new UInt256[0], MinerTransaction = minerTx //(MinerTransaction)Transactions[TransactionHashes[0]], }; ConsensusPayload prepPayload = new ConsensusPayload { Version = 0, PrevHash = mockConsensusContext.Object.PrevHash, BlockIndex = mockConsensusContext.Object.BlockIndex, ValidatorIndex = (ushort)mockConsensusContext.Object.MyIndex, ConsensusMessage = prep }; mockConsensusContext.Setup(mr => mr.MakePrepareRequest()).Returns(prepPayload); // ============================================================================ // creating ConsensusService actor // ============================================================================ TestActorRef <ConsensusService> actorConsensus = ActorOfAsTestActorRef <ConsensusService>( Akka.Actor.Props.Create(() => new ConsensusService(subscriber, subscriber, mockConsensusContext.Object)) ); Console.WriteLine("will trigger OnPersistCompleted!"); actorConsensus.Tell(new Blockchain.PersistCompleted { Block = new Block { Version = header.Version, PrevHash = header.PrevHash, MerkleRoot = header.MerkleRoot, Timestamp = header.Timestamp, Index = header.Index, ConsensusData = header.ConsensusData, NextConsensus = header.NextConsensus } }); // OnPersist will not launch timer, we need OnStart Console.WriteLine("will start consensus!"); actorConsensus.Tell(new ConsensusService.Start()); Console.WriteLine("OnTimer should expire!"); Console.WriteLine("Waiting for subscriber message!"); // Timer should expire in one second (block_received_time at :01, initialized at :02) var answer = subscriber.ExpectMsg <LocalNode.SendDirectly>(); Console.WriteLine($"MESSAGE 1: {answer}"); //var answer2 = subscriber.ExpectMsg<LocalNode.SendDirectly>(); // expects to fail! // ============================================================================ // finalize ConsensusService actor // ============================================================================ //Thread.Sleep(4000); Sys.Stop(actorConsensus); TimeProvider.ResetToDefault(); Assert.AreEqual(1, 1); }