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