Example #1
0
        public ExecutionStatus DistributeCycleRewardsAndPenalties(UInt256 cycle, SystemContractExecutionFrame frame)
        {
            Logger.LogDebug($"DistributeCycleRewardsAndPenalties({cycle})");
            if (cycle.ToBigInteger() != GetConsensusGeneration(frame))
            {
                Logger.LogWarning($"Invalid cycle: {cycle}, now is {GetConsensusGeneration(frame)}");
                return(ExecutionStatus.Ok);
            }

            if (!MsgSender().IsZero())
            {
                Logger.LogError("!MsgSender().IsZero(): governance function called by non-zero address");
                return(ExecutionStatus.ExecutionHalted);
            }

            var txFeesAmount = GetCollectedFees();

            SetCollectedFees(new Money(0));

            if (txFeesAmount > Money.Zero)
            {
                _context.Snapshot.Balances.SubBalance(
                    ContractRegisterer.GovernanceContract, txFeesAmount
                    );
            }

            var totalReward = GetBlockReward().ToMoney() * (int)StakingContract.CycleDuration + txFeesAmount;

            _context.Sender = ContractRegisterer.GovernanceContract;
            var staking = new StakingContract(_context);

            staking.DistributeRewardsAndPenalties(totalReward.ToUInt256(), frame);
            Emit(GovernanceInterface.EventDistributeCycleRewardsAndPenalties, totalReward.ToUInt256());
            return(ExecutionStatus.Ok);
        }
Example #2
0
        public void Test_OneNodeCycle()
        {
            var tx = new TransactionReceipt();

            var keyPair = new EcdsaKeyPair("0xD95D6DB65F3E2223703C5D8E205D98E3E6B470F067B0F94F6C6BF73D4301CE48"
                                           .HexToBytes().ToPrivateKey());

            byte[] publicKey = CryptoUtils.EncodeCompressed(keyPair.PublicKey);
            var    sender    = keyPair.PublicKey.GetAddress();

            var context  = new InvocationContext(sender, _stateManager.LastApprovedSnapshot, tx);
            var contract = new StakingContract(context);

            var stakeAmount = BigInteger.Pow(10, 21);

            // Set balance for the staker
            {
                context.Snapshot.Balances.SetBalance(sender, Money.Parse("1000"));
                Assert.AreEqual(Money.Parse("1000"), context.Snapshot.Balances.GetBalance(sender));
            }

            // Become staker
            {
                var input = ContractEncoder.Encode(StakingInterface.MethodBecomeStaker, publicKey, stakeAmount.ToUInt256());
                var call  = _contractRegisterer.DecodeContract(context, ContractRegisterer.StakingContract, input);
                Assert.IsNotNull(call);
                var frame = new SystemContractExecutionFrame(call !, context, input, 100_000_000);
                Assert.AreEqual(ExecutionStatus.Ok, contract.BecomeStaker(publicKey, stakeAmount.ToUInt256(), frame));
            }

            // Get stake
            {
                var input = ContractEncoder.Encode(StakingInterface.MethodGetStake, sender);
                var call  = _contractRegisterer.DecodeContract(context, ContractRegisterer.StakingContract, input);
                Assert.IsNotNull(call);
                var frame = new SystemContractExecutionFrame(call !, context, input, 100_000_000);
                Assert.AreEqual(ExecutionStatus.Ok, contract.GetStake(sender, frame));
                Assert.AreEqual(Money.Parse("1000"), frame.ReturnValue.ToUInt256().ToMoney());
            }

            // Able to validator
            {
                var input = ContractEncoder.Encode(StakingInterface.MethodIsAbleToBeValidator, sender);
                var call  = _contractRegisterer.DecodeContract(context, ContractRegisterer.StakingContract, input);
                Assert.IsNotNull(call);
                var frame = new SystemContractExecutionFrame(call !, context, input, 100_000_000);
                Assert.AreEqual(ExecutionStatus.Ok, contract.IsAbleToBeValidator(sender, frame));
                //Assert.AreEqual(1, BitConverter.ToInt32(frame.ReturnValue, 0));
            }
        }
Example #3
0
        public void Start(RunOptions options)
        {
            var configManager          = _container.Resolve <IConfigManager>();
            var blockManager           = _container.Resolve <IBlockManager>();
            var consensusManager       = _container.Resolve <IConsensusManager>();
            var validatorStatusManager = _container.Resolve <IValidatorStatusManager>();
            var transactionVerifier    = _container.Resolve <ITransactionVerifier>();
            var validatorManager       = _container.Resolve <IValidatorManager>();
            var blockSynchronizer      = _container.Resolve <IBlockSynchronizer>();
            var networkManager         = _container.Resolve <INetworkManager>();
            var commandManager         = _container.Resolve <IConsoleManager>();
            var rpcManager             = _container.Resolve <IRpcManager>();
            var stateManager           = _container.Resolve <IStateManager>();
            var wallet                     = _container.Resolve <IPrivateWallet>();
            var metricsService             = _container.Resolve <IMetricsService>();
            var snapshotIndexRepository    = _container.Resolve <ISnapshotIndexRepository>();
            var localTransactionRepository = _container.Resolve <ILocalTransactionRepository>();
            var NodeRetrieval              = _container.Resolve <INodeRetrieval>();
            var dbContext                  = _container.Resolve <IRocksDbContext>();
            var storageManager             = _container.Resolve <IStorageManager>();
            var transactionPool            = _container.Resolve <ITransactionPool>();

            // check if compacting db was started but not finished
            var dbShrink = _container.Resolve <IDbShrink>();

            if (!dbShrink.IsStopped())
            {
                throw new Exception($"Compacting db was started with depth: {dbShrink.GetDbShrinkDepth()}"
                                    + " by deleting nodes from old snapshot but was not finished.");
            }

            // set chainId from config
            var chainId = configManager.GetConfig <NetworkConfig>("network")?.ChainId ?? 0;

            if (chainId == 0)
            {
                throw new Exception("chainId is not defined in the config file");
            }
            var newChainId = configManager.GetConfig <NetworkConfig>("network")?.NewChainId ?? 0;

            if (newChainId == 0)
            {
                throw new Exception("newChainId is not defined in the config file");
            }

            Logger.LogInformation($"ChainId {chainId}, newChainId {newChainId}");
            TransactionUtils.SetChainId(chainId, newChainId);

            var version = Assembly.GetEntryAssembly() !
                          .GetCustomAttribute <AssemblyInformationalVersionAttribute>()
                          .InformationalVersion;

            Logger.LogInformation($"Version: {version}");

            // set cycle and validatorCount
            StakingContract.Initialize(configManager.GetConfig <NetworkConfig>("network"));

            // set hardfork heights
            Logger.LogInformation($"Setting hardfork heights.");
            var hardforkConfig = configManager.GetConfig <HardforkConfig>("hardfork") ??
                                 throw new Exception("No 'hardfork' section in config file");

            HardforkHeights.SetHardforkHeights(hardforkConfig);

            rpcManager.Start();

            if (options.RollBackTo.HasValue)
            {
                Logger.LogWarning($"Performing roll back to block {options.RollBackTo.Value}");
                var snapshot = snapshotIndexRepository.GetSnapshotForBlock(options.RollBackTo.Value);
                stateManager.RollbackTo(snapshot);
                wallet.DeleteKeysAfterBlock(options.RollBackTo.Value);
                stateManager.Commit();
                Logger.LogWarning($"Rollback to block {options.RollBackTo.Value} complete");
            }


            localTransactionRepository.SetWatchAddress(wallet.EcdsaKeyPair.PublicKey.GetAddress());

            if (blockManager.TryBuildGenesisBlock())
            {
                Logger.LogInformation("Generated genesis block");
            }

            var genesisBlock = stateManager.LastApprovedSnapshot.Blocks.GetBlockByHeight(0)
                               ?? throw new Exception("Genesis block was not persisted");

            Logger.LogInformation("Genesis Block: " + genesisBlock.Hash.ToHex());
            Logger.LogInformation($" + prevBlockHash: {genesisBlock.Header.PrevBlockHash.ToHex()}");
            Logger.LogInformation($" + merkleRoot: {genesisBlock.Header.MerkleRoot.ToHex()}");
            Logger.LogInformation($" + nonce: {genesisBlock.Header.Nonce}");
            Logger.LogInformation($" + transactionHashes: {genesisBlock.TransactionHashes.ToArray().Length}");
            foreach (var s in genesisBlock.TransactionHashes)
            {
                Logger.LogInformation($" + - {s.ToHex()}");
            }
            Logger.LogInformation($" + hash: {genesisBlock.Hash.ToHex()}");

            Logger.LogInformation("Current block height: " + blockManager.GetHeight());
            Logger.LogInformation($"Node public key: {wallet.EcdsaKeyPair.PublicKey.EncodeCompressed().ToHex()}");
            Logger.LogInformation($"Node address: {wallet.EcdsaKeyPair.PublicKey.GetAddress().ToHex()}");

            if (options.SetStateTo.Any())
            {
                List <string> args = options.SetStateTo.ToList();
                //    System.Console.WriteLine(args);
                ulong blockNumber = 0;
                if (!(args is null) && args.Count > 0)
                {
                    blockNumber = Convert.ToUInt64(args[0]);
                }
                FastSynchronizerBatch.StartSync(stateManager, dbContext, snapshotIndexRepository,
                                                storageManager.GetVersionFactory(), blockNumber);
            }

            /*    if(blockManager.GetHeight()==0)
             *  FastSynchronizerBatch.StartSync(stateManager, dbContext, snapshotIndexRepository,
             *                                  storageManager.GetVersionFactory(), 0); */

            var networkConfig = configManager.GetConfig <NetworkConfig>("network") ??
                                throw new Exception("No 'network' section in config file");

            metricsService.Start();
            networkManager.Start();
            transactionVerifier.Start();
            commandManager.Start(wallet.EcdsaKeyPair);

            // pending transactions are restored from pool repository to in-memory storage
            // it's important to restore pool after transactionVerifier and before blockSynchronizer starts
            transactionPool.Restore();

            blockSynchronizer.Start();
            Logger.LogInformation("Synchronizing blocks...");
            blockSynchronizer.SynchronizeWith(
                validatorManager.GetValidatorsPublicKeys((long)blockManager.GetHeight())
                .Where(key => !key.Equals(wallet.EcdsaKeyPair.PublicKey))
                );
            Logger.LogInformation("Block synchronization finished, starting consensus...");
            consensusManager.Start(blockManager.GetHeight() + 1);
            validatorStatusManager.Start(false);

            System.Console.CancelKeyPress += (sender, e) =>
            {
                System.Console.WriteLine("Interrupt received. Exiting...");
                _interrupt = true;
                Dispose();
            };

            while (!_interrupt)
            {
                Thread.Sleep(1000);
            }
        }