Beispiel #1
0
        private void ApplyMinerRewards(Block block, IBlockTracer tracer)
        {
            if (_logger.IsTrace)
            {
                _logger.Trace("Applying miner rewards:");
            }
            var rewards = _rewardCalculator.CalculateRewards(block);

            for (int i = 0; i < rewards.Length; i++)
            {
                BlockReward reward = rewards[i];

                ITxTracer txTracer = null;
                if (tracer.IsTracingRewards)
                {
                    // we need this tracer to be able to track any potential miner account creation
                    txTracer = tracer.StartNewTxTrace(null);
                }

                ApplyMinerReward(block, reward);

                if (tracer.IsTracingRewards)
                {
                    tracer.EndTxTrace();
                    tracer.ReportReward(reward.Address, reward.RewardType.ToLowerString(), reward.Value);
                    if (txTracer?.IsTracingState ?? false)
                    {
                        _stateProvider.Commit(_specProvider.GetSpec(block.Number), txTracer);
                    }
                }
            }
        }
        public void calculates_rewards_correctly_for_external_addresses()
        {
            _block.Header.Number = 10;
            _block.Body          = new BlockBody(_block.Body.Transactions, new[]
            {
                Build.A.BlockHeader.WithBeneficiary(TestItem.Addresses[0]).WithNumber(9).TestObject,
                Build.A.BlockHeader.WithBeneficiary(TestItem.Addresses[1]).WithNumber(8).TestObject
            });

            var expected = new BlockReward[]
            {
                new BlockReward(TestItem.AddressA, 1, BlockRewardType.External),
                new BlockReward(TestItem.AddressB, 3, BlockRewardType.External),
                new BlockReward(TestItem.AddressC, 5, BlockRewardType.External),
                new BlockReward(TestItem.AddressD, 8, BlockRewardType.External),
            };

            SetupBlockRewards(new Dictionary <Address, BlockReward[]>()
            {
                { _address10, expected }
            });
            var calculator = new AuRaRewardCalculator(_auraParameters, _abiEncoder, _transactionProcessor);
            var result     = calculator.CalculateRewards(_block);

            result.Should().BeEquivalentTo(expected);
        }
Beispiel #3
0
        // TODO: block processor pipeline
        private void ApplyMinerRewards(Block block, IBlockTracer tracer, IReleaseSpec spec)
        {
            if (_logger.IsTrace)
            {
                _logger.Trace("Applying miner rewards:");
            }
            BlockReward[] rewards = _rewardCalculator.CalculateRewards(block);
            for (int i = 0; i < rewards.Length; i++)
            {
                BlockReward reward = rewards[i];

                ITxTracer txTracer = NullTxTracer.Instance;
                if (tracer.IsTracingRewards)
                {
                    // we need this tracer to be able to track any potential miner account creation
                    txTracer = tracer.StartNewTxTrace(null);
                }

                ApplyMinerReward(block, reward, spec);

                if (tracer.IsTracingRewards)
                {
                    tracer.EndTxTrace();
                    tracer.ReportReward(reward.Address, reward.RewardType.ToLowerString(), reward.Value);
                    if (txTracer.IsTracingState)
                    {
                        _stateProvider.Commit(spec, txTracer);
                    }
                }
            }
        }
        public void calculates_rewards_correctly_for_ommers(long blockNumber, long expectedReward)
        {
            _block.Header.Number = blockNumber;
            _block.Body          = new BlockBody(_block.Body.Transactions, new[]
            {
                Build.A.BlockHeader.WithBeneficiary(TestItem.AddressB).WithNumber(blockNumber - 1).TestObject,
                Build.A.BlockHeader.WithBeneficiary(TestItem.AddressD).WithNumber(blockNumber - 2).TestObject
            });

            var expected = new BlockReward[]
            {
                new BlockReward(_block.Beneficiary, expectedReward, BlockRewardType.Block),
                new BlockReward(_block.Body.Ommers[0].Beneficiary, expectedReward, BlockRewardType.Uncle),
                new BlockReward(_block.Body.Ommers[1].Beneficiary, expectedReward, BlockRewardType.Uncle),
            };

            SetupBlockRewards(new Dictionary <Address, BlockReward[]>()
            {
                { _address10, expected }
            });
            var calculator = new AuRaRewardCalculator(_auraParameters, _abiEncoder, _transactionProcessor);
            var result     = calculator.CalculateRewards(_block);

            result.Should().BeEquivalentTo(expected);
        }
        public void EvaluatePromotion_GetBestPaymentReward()
        {
            //Agganre
            var blockReward = new BlockReward().WithChildrens(new RewardPaymentGetOfAbs()
            {
                Amount = 10m, PaymentMethod = "PayTest"
            });
            var dynamicPromotion = new DynamicPromotion
            {
                DynamicExpression = AbstractTypeFactory <PromotionConditionAndRewardTree> .TryCreateInstance()
            };

            dynamicPromotion.DynamicExpression.WithChildrens(blockReward);

            var evalPolicy = GetPromotionEvaluationPolicy(new[] { dynamicPromotion });
            var productA   = new ProductPromoEntry {
                ProductId = "ProductA", Price = 100, Quantity = 1
            };
            var context = new PromotionEvaluationContext
            {
                PaymentMethodCode  = "PayTest",
                PaymentMethodPrice = 5m,
                PromoEntries       = new[] { productA }
            };

            //Act
            var rewards = evalPolicy.EvaluatePromotionAsync(context).GetAwaiter().GetResult().Rewards.OfType <PaymentReward>().ToList();

            //Assert
            Assert.Equal(10m, rewards.First().Amount);
            Assert.True(rewards.First().IsValid);
        }
Beispiel #6
0
        private void ApplyMinerRewards(Block block, IBlockTracer tracer)
        {
            if (_logger.IsTrace)
            {
                _logger.Trace("Applying miner rewards:");
            }
            var rewards = _rewardCalculator.CalculateRewards(block);

            for (int i = 0; i < rewards.Length; i++)
            {
                BlockReward reward = rewards[i];

                ITxTracer txTracer = null;
                if (tracer.IsTracingRewards)
                {
                    txTracer = tracer.StartNewTxTrace(null);
                }

                ApplyMinerReward(block, reward, tracer.IsTracingRewards ? tracer : NullBlockTracer.Instance);

                if (tracer.IsTracingRewards)
                {
                    tracer.EndTxTrace();
                    tracer.ReportReward(reward.Address, reward.RewardType.ToLowerString(), (UInt256)reward.Value);
                    if (txTracer?.IsTracingState ?? false)
                    {
                        _stateProvider.Commit(_specProvider.GetSpec(block.Number), txTracer);
                    }
                }
            }
        }
Beispiel #7
0
 public override string ToString()
 {
     return("TAG: " + TagName + " | Name:" + FullName + " | Algo: " + Algo + " | BTC/day: " +
            BtcPerDay.ToString("#.00000000") + " | Coins/day: " + CoinsPerDay.ToString("#.00000000") +
            GetExchanges() +
            " | Weighted price: " + WeightedBtcPrice.ToString("#.00000000") + " | Total volume: " +
            TotalExchange.BtcVolume.ToString("#.0000") + " | Difficulty: " + Difficulty.ToString("#.###") +
            " | Blockreward: " + BlockReward.ToString("#.###"));
 }
Beispiel #8
0
        public void calculates_rewards_correctly_after_contract_transition(long blockNumber, long expectedReward)
        {
            _block.Number = blockNumber;
            var expected = new BlockReward(_block.Beneficiary, expectedReward, BlockRewardType.Block);

            SetupBlockRewards(expected);
            var calculator = new AuRaRewardCalculator(_auraParameters, _abiEncoder, _transactionProcessor);
            var result     = calculator.CalculateRewards(_block);

            result.Should().BeEquivalentTo(expected);
        }
        public void calculates_rewards_correctly_after_contract_transition(long blockNumber, ulong expectedReward)
        {
            _block.Header.Number = blockNumber;
            var expected = new BlockReward(_block.Beneficiary, expectedReward, BlockRewardType.External);

            SetupBlockRewards(new Dictionary <Address, BlockReward[]>()
            {
                { _address10, new[] { expected } }
            });
            var calculator = new AuRaRewardCalculator(_auraParameters, _abiEncoder, _transactionProcessor);
            var result     = calculator.CalculateRewards(_block);

            result.Should().BeEquivalentTo(expected);
        }
Beispiel #10
0
        private void ApplyMinerReward(Block block, BlockReward reward)
        {
            if (_logger.IsTrace)
            {
                _logger.Trace($"  {(BigInteger) reward.Value / (BigInteger) Unit.Ether:N3}{Unit.EthSymbol} for account at {reward.Address}");
            }

            if (!_stateProvider.AccountExists(reward.Address))
            {
                _stateProvider.CreateAccount(reward.Address, reward.Value);
            }
            else
            {
                _stateProvider.AddToBalance(reward.Address, reward.Value, _specProvider.GetSpec(block.Number));
            }
        }
Beispiel #11
0
 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();
     }
     BlockReward = reader.ReadSerializable <BlockReward>();
     if (BlockReward.Hash != TransactionHashes[0])
     {
         throw new FormatException();
     }
     StateRootSignature = reader.ReadBytes(64);
 }
        public void calculates_rewards_correctly_after_subsequent_contract_transitions(long blockNumber, long expectedReward, Address address)
        {
            _auraParameters.BlockRewardContractTransitions = new Dictionary <long, Address>()
            {
                { 50, _address50 },
                { 150, _address150 }
            };
            _block.Header.Number = blockNumber;
            var expected = new BlockReward(_block.Beneficiary, expectedReward, BlockRewardType.Block);

            SetupBlockRewards(new Dictionary <Address, BlockReward[]>()
            {
                { address, new[] { expected } }
            });
            var calculator = new AuRaRewardCalculator(_auraParameters, _abiEncoder, _transactionProcessor);
            var result     = calculator.CalculateRewards(_block);

            result.Should().BeEquivalentTo(expected);
        }
Beispiel #13
0
        private void Fill()
        {
            IEnumerable <Transaction> memoryPoolTransactions = Blockchain.Singleton.MemPool.GetSortedVerifiedTransactions();

            foreach (IPolicyPlugin plugin in Plugin.Policies)
            {
                memoryPoolTransactions = plugin.FilterForBlock(memoryPoolTransactions);
            }
            List <Transaction> transactions = memoryPoolTransactions.ToList();
            Fixed8             amountNetFee = Block.CalculateNetFee(transactions);

            TransactionOutput[] outputs = new[] { new TransactionOutput
                                                  {
                                                      AssetId    = Blockchain.GoverningToken.Hash,
                                                      Value      = Blockchain.Singleton.GetBlockReward() + amountNetFee,
                                                      ScriptHash = wallet.GetChangeAddress()
                                                  } };
            while (true)
            {
                ulong       nonce = GetNonce();
                BlockReward tx    = new BlockReward
                {
                    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(), this.PrevHeader().Timestamp + 1);
        }
Beispiel #14
0
        private BlockReward[] CalculateRewardsWithContract(Block block)
        {
            (Address[] beneficieries, ushort[] kinds) GetBeneficiaries()
            {
                var length = block.Ommers.Length + 1;

                Address[] beneficiariesList = new Address[length];
                ushort[]  kindsList         = new ushort[length];
                beneficiariesList[0] = block.Beneficiary;
                kindsList[0]         = RewardContract.Definition.BenefactorKind.Author;

                for (int i = 0; i < block.Ommers.Length; i++)
                {
                    var uncle = block.Ommers[i];
                    if (RewardContract.Definition.BenefactorKind.TryGetUncle(block.Number - uncle.Number, out var kind))
                    {
                        beneficiariesList[i + 1] = uncle.Beneficiary;
                        kindsList[i + 1]         = kind;
                    }
                }

                return(beneficiariesList, kindsList);
            }

            var(beneficiaries, kinds) = GetBeneficiaries();
            var transaction = _contract.Reward(beneficiaries, kinds);

            _contract.InvokeTransaction(block.Header, _transactionProcessor, transaction, _tracer);
            var(addresses, rewards) = _contract.DecodeRewards(_tracer.ReturnValue);

            var blockRewards = new BlockReward[addresses.Length];

            for (int index = 0; index < addresses.Length; index++)
            {
                var address = addresses[index];
                blockRewards[index] = new BlockReward(address, rewards[index], GetBlockRewardType(address, beneficiaries, kinds, index));
            }

            return(blockRewards);
        }
Beispiel #15
0
        public void calculates_rewards_correctly_for_ommers(long blockNumber, long expectedReward)
        {
            _block.Number      = blockNumber;
            _block.Body.Ommers = new[]
            {
                Prepare.A.BlockHeader().WithBeneficiary(Address.FromNumber(777)).WithNumber(blockNumber - 1).TestObject,
                Prepare.A.BlockHeader().WithBeneficiary(Address.FromNumber(888)).WithNumber(blockNumber - 2).TestObject
            };

            var expected = new BlockReward[]
            {
                new BlockReward(_block.Beneficiary, expectedReward, BlockRewardType.Block),
                new BlockReward(_block.Body.Ommers[0].Beneficiary, expectedReward, BlockRewardType.Uncle),
                new BlockReward(_block.Body.Ommers[1].Beneficiary, expectedReward, BlockRewardType.Uncle),
            };

            SetupBlockRewards(expected);
            var calculator = new AuRaRewardCalculator(_auraParameters, _abiEncoder, _transactionProcessor);
            var result     = calculator.CalculateRewards(_block);

            result.Should().BeEquivalentTo(expected);
        }
Beispiel #16
0
        public void calculates_rewards_correctly_for_external_addresses()
        {
            _block.Number      = 10;
            _block.Body.Ommers = new[]
            {
                Prepare.A.BlockHeader().WithBeneficiary(Address.FromNumber(777)).WithNumber(9).TestObject,
                Prepare.A.BlockHeader().WithBeneficiary(Address.FromNumber(888)).WithNumber(8).TestObject
            };

            var expected = new BlockReward[]
            {
                new BlockReward(TestItem.AddressA, 1, BlockRewardType.External),
                new BlockReward(TestItem.AddressB, 3, BlockRewardType.External),
                new BlockReward(TestItem.AddressC, 5, BlockRewardType.External),
                new BlockReward(TestItem.AddressD, 8, BlockRewardType.External),
            };

            SetupBlockRewards(expected);
            var calculator = new AuRaRewardCalculator(_auraParameters, _abiEncoder, _transactionProcessor);
            var result     = calculator.CalculateRewards(_block);

            result.Should().BeEquivalentTo(expected);
        }
Beispiel #17
0
        private BlockReward[] CalculateRewardsWithContract(Block block, IRewardContract contract)
        {
            (Address[] beneficieries, ushort[] kinds) GetBeneficiaries()
            {
                var length = block.Uncles.Length + 1;

                Address[] beneficiariesList = new Address[length];
                ushort[]  kindsList         = new ushort[length];
                beneficiariesList[0] = block.Beneficiary;
                kindsList[0]         = BenefactorKind.Author;

                for (int i = 0; i < block.Uncles.Length; i++)
                {
                    var uncle = block.Uncles[i];
                    if (BenefactorKind.TryGetUncle(block.Number - uncle.Number, out var kind))
                    {
                        beneficiariesList[i + 1] = uncle.Beneficiary;
                        kindsList[i + 1]         = kind;
                    }
                }

                return(beneficiariesList, kindsList);
            }

            var(beneficiaries, kinds) = GetBeneficiaries();
            var(addresses, rewards)   = contract.Reward(block.Header, beneficiaries, kinds);

            var blockRewards = new BlockReward[addresses.Length];

            for (int index = 0; index < addresses.Length; index++)
            {
                var address = addresses[index];
                blockRewards[index] = new BlockReward(address, rewards[index], BlockRewardType.External);
            }

            return(blockRewards);
        }
Beispiel #18
0
 public void TestSetup()
 {
     uut = new BlockReward();
 }
Beispiel #19
0
        public void DynamicPromotion_Clone()
        {
            var blockCustomer = new BlockCustomerCondition()
                                .WithAvailConditions(
                new ConditionIsRegisteredUser(),
                new ConditionIsEveryone(),
                new ConditionIsFirstTimeBuyer(),
                new UserGroupsContainsCondition()
            {
                Group = "11"
            }
                );
            var blockCatalog = new BlockCatalogCondition()
                               .WithAvailConditions(
                new ConditionCategoryIs()
            {
                CategoryId = "11", CategoryName = "", ExcludingCategoryIds = new string[] { "1", "2" }, ExcludingProductIds = new string[] { "3", "4" }
            },
                new ConditionCodeContains()
            {
                Keyword = "keyword"
            },
                new ConditionCurrencyIs()
            {
                Currency = "USD"
            },
                new ConditionEntryIs()
            {
                ProductIds = new string[] { "1", "2" }, ProductNames = new string[] { "name1", "name2" }
            },
                new ConditionInStockQuantity()
            {
                CompareCondition = "CND", Quantity = 111, QuantitySecond = 222
            },
                new ConditionHasNoSalePrice()
                );
            var blockCart = new BlockCartCondition()
                            .WithAvailConditions(
                new ConditionAtNumItemsInCart()
            {
                CompareCondition = "CND", ExcludingCategoryIds = new string[] { "1", "2" }, ExcludingProductIds = new string[] { "3", "4" }, NumItem = 111, NumItemSecond = 222
            },
                new ConditionAtNumItemsInCategoryAreInCart()
            {
                CategoryId = "catid", CategoryName = "catname", CompareCondition = "CND", ExcludingCategoryIds = new string[] { "1", "2" }, ExcludingProductIds = new string[] { "3", "4" }, NumItem = 111, NumItemSecond = 222
            },
                new ConditionAtNumItemsOfEntryAreInCart()
            {
                CompareCondition = "CND", NumItem = 111, NumItemSecond = 222, ProductId = "Id", ProductName = "Name"
            },
                new ConditionCartSubtotalLeast()
            {
                CompareCondition = "CND", ExcludingCategoryIds = new string[] { "1", "2" }, ExcludingProductIds = new string[] { "3", "4" }, SubTotal = 111, SubTotalSecond = 222
            }
                );
            var blockReward = new BlockReward()
                              .WithAvailConditions(
                new RewardCartGetOfAbsSubtotal()
            {
                Amount = 444
            },
                new RewardCartGetOfRelSubtotal()
            {
                Amount = 444, MaxLimit = 555
            },
                new RewardItemGetFreeNumItemOfProduct()
            {
                NumItem = 55, ProductId = "Id", ProductName = "Name"
            },
                new RewardItemGetOfAbs()
            {
                Amount = 444, ProductId = "Id", ProductName = "Name"
            },
                new RewardItemGetOfAbsForNum()
            {
                Amount = 444, ProductId = "Id", ProductName = "Name", NumItem = 23
            },
                new RewardItemGetOfRel()
            {
                Amount = 444, ProductId = "Id", ProductName = "Name", MaxLimit = 23
            },
                new RewardItemGetOfRelForNum()
            {
                Amount = 444, ProductId = "Id", ProductName = "Name", MaxLimit = 23, NumItem = 32
            },
                new RewardItemGiftNumItem()
            {
                CategoryId = "catid", CategoryName = "catname", Description = "description", ProductId = "productId", ProductName = "ptoductName", Name = "Name", ImageUrl = "url:\\", MeasureUnit = "px", Quantity = 33
            },
                new RewardShippingGetOfAbsShippingMethod()
            {
                Amount = 444, ShippingMethod = "shipMethod"
            },
                new RewardShippingGetOfRelShippingMethod()
            {
                Amount = 444, ShippingMethod = "shipMethod", MaxLimit = 22
            },
                new RewardPaymentGetOfAbs()
            {
                Amount = 444, PaymentMethod = "payMethod"
            },
                new RewardPaymentGetOfRel()
            {
                Amount = 444, PaymentMethod = "payMethod", MaxLimit = 22
            },
                new RewardItemForEveryNumInGetOfRel()
            {
                Amount = 444, ForNthQuantity = 77, InEveryNthQuantity = 78, MaxLimit = 22, ItemLimit = 23, Product = new ProductContainer()
                {
                    ProductId = "prodID", ProductName = "prodName"
                }
            },
                new RewardItemForEveryNumOtherItemInGetOfRel()
            {
                Amount = 444, ForNthQuantity = 77, InEveryNthQuantity = 78, MaxLimit = 22, ItemLimit = 23, Product = new ProductContainer()
                {
                    ProductId = "prodID", ProductName = "prodName"
                }, ConditionalProduct = new ProductContainer()
                {
                    ProductId = "condProdID", ProductName = "condProdName"
                }
            }
                );

            var dynamicPromotion = new DynamicPromotion
            {
                DynamicExpression = AbstractTypeFactory <PromotionConditionAndRewardTree> .TryCreateInstance()
            };

            dynamicPromotion.DynamicExpression.WithChildrens(
                blockCustomer,
                blockCatalog,
                blockCart,
                blockReward
                );

            dynamicPromotion.AssertCloneIndependency();
        }
Beispiel #20
0
        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

            BlockReward minerTx = new BlockReward
            {
                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],
                BlockReward        = minerTx, //(BlockReward)Transactions[TransactionHashes[0]],
                StateRootSignature = new byte[64]
            };

            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);
        }