public ExecutionStatus KeyGenCommit(UInt256 cycle, byte[] commitment, byte[][] encryptedRows, SystemContractExecutionFrame frame) { Logger.LogDebug( $"KeyGenCommit({commitment.ToHex()}, [{string.Join(", ", encryptedRows.Select(r => r.ToHex()))}])"); if (cycle.ToBigInteger() != GetConsensusGeneration(frame)) { Logger.LogWarning($"Invalid cycle: {cycle}, now is {GetConsensusGeneration(frame)}"); return(ExecutionStatus.Ok); } try { var c = Commitment.FromBytes(commitment); if (!c.IsValid()) { throw new Exception(); } var n = _nextValidators.Get().Length / CryptoUtils.PublicKeyLength; if (c.Degree != (n - 1) / 3) { throw new Exception(); } if (encryptedRows.Length != n) { throw new Exception(); } } catch { Logger.LogError("GovernanceContract is halted in KeyGenCommit"); return(ExecutionStatus.ExecutionHalted); } Emit(GovernanceInterface.EventKeygenCommit, commitment, encryptedRows); frame.ReturnValue = new byte[] { }; frame.UseGas(GasMetering.KeygenCommitCost); return(ExecutionStatus.Ok); }
public ulong GetLastSuccessfulKeygenBlock() { var storageVariable = new StorageVariable( ContractRegisterer.GovernanceContract, _stateManager.LastApprovedSnapshot.Storage, new BigInteger(8).ToUInt256() ); var rawValue = storageVariable.Get(); if (rawValue.Length == 0) { return(0); } return((ulong)rawValue.ToUInt256().ToBigInteger()); }
private int?GetPlayersCount() { var count = _playersCount.Get(); Logger.LogTrace($"Players count: {count.ToHex()}"); if (count.Length == 0) { return(null); } try { return(count.AsReadOnlySpan().ToInt32()); } catch (Exception) { return(null); } }
private PublicKey GetTpkeKey() { var tpkePublicKey = _tpkeKey.Get(); return(PublicKey.FromBytes(tpkePublicKey)); }
private Money GetCollectedFees() { var fees = _collectedFees.Get(); return(fees.ToUInt256().ToMoney()); }
private PublicKeySet GetTSKeys() { var tsKeys = _tsKeys.Get(); return(PublicKeySet.FromBytes(tsKeys)); }
private UInt256 GetBlockReward() { var reward = _blockReward.Get(); return(reward.ToUInt256()); }
// Every time a node starts, it first tries to build the genesis block public bool TryBuildGenesisBlock() { // genesis block is built from the config.json file // genesis block mints tokens to the validators for the first cycle var genesisBlock = _genesisBuilder.Build(); // if genesis block can already be found, we return immediately if (_stateManager.LastApprovedSnapshot.Blocks.GetBlockByHeight(0) != null) { return(false); } var snapshot = _stateManager.NewSnapshot(); var genesisConfig = _configManager.GetConfig <GenesisConfig>("genesis"); if (genesisConfig is null) { return(false); } genesisConfig.ValidateOrThrow(); var initialConsensusState = new ConsensusState( genesisConfig.ThresholdEncryptionPublicKey.HexToBytes(), genesisConfig.Validators.Select(v => new ValidatorCredentials ( v.EcdsaPublicKey.HexToBytes().ToPublicKey(), v.ThresholdSignaturePublicKey.HexToBytes() )).ToArray() ); snapshot.Validators.SetConsensusState(initialConsensusState); // stake delegation happens even before genesis block // stake delegation means - some other address stakes for the validators // config.json keeps the stakerAddress and the stakeAmount for each of the validators // init system contracts storage var dummyStakerPub = new string('f', CryptoUtils.PublicKeyLength * 2).HexToBytes(); snapshot.Storage.SetRawValue( ContractRegisterer.StakingContract, new BigInteger(6).ToUInt256().Buffer, dummyStakerPub ); // TODO: get rid of explicit numbering of fields var initialVrfSeed = Encoding.ASCII.GetBytes("test"); snapshot.Storage.SetRawValue( ContractRegisterer.StakingContract, new BigInteger(7).ToUInt256().Buffer, initialVrfSeed ); var initialBlockReward = Money.Parse(genesisConfig.BlockReward).ToUInt256().ToBytes(); snapshot.Storage.SetRawValue( ContractRegisterer.GovernanceContract, new BigInteger(3).ToUInt256().Buffer, initialBlockReward ); var initialBasicGasPrice = Money.Parse(genesisConfig.BasicGasPrice).ToUInt256().ToBytes(); snapshot.Storage.SetRawValue( ContractRegisterer.GovernanceContract, new BigInteger(8).ToUInt256().Buffer, initialBasicGasPrice ); // The followings are the variables used in stakingContract // This variables are stored in the storage snapshot and is a part of the chain // To understand the what each variables represent, refer to StakingContract.cs // We do the stake delegation even before the execution of genesis block var _userToStake = new StorageMapping( ContractRegisterer.StakingContract, snapshot.Storage, new BigInteger(3).ToUInt256() ); var _stakers = new StorageVariable( ContractRegisterer.StakingContract, snapshot.Storage, new BigInteger(6).ToUInt256() ); var _userToPubKey = new StorageMapping( ContractRegisterer.StakingContract, snapshot.Storage, new BigInteger(2).ToUInt256() ); var _pubKeyToStaker = new StorageMapping( ContractRegisterer.StakingContract, snapshot.Storage, new BigInteger(12).ToUInt256() ); var _userToStartCycle = new StorageMapping( ContractRegisterer.StakingContract, snapshot.Storage, new BigInteger(4).ToUInt256() ); foreach (var validator in genesisConfig.Validators) { if (validator.StakeAmount == null || validator.StakerAddress == null) { continue; } var validatorPublicKey = validator.EcdsaPublicKey.HexToBytes(); var validatorAddress = Hepler.PublicKeyToAddress(validatorPublicKey).ToBytes(); var stakerAddress = validator.StakerAddress.HexToBytes(); // add balance to staking contract var stakeAmount = Money.Parse(validator.StakeAmount); snapshot.Balances.AddBalance(ContractRegisterer.StakingContract, stakeAmount, true); // set stake value _userToStake.SetValue(validatorAddress, stakeAmount.ToUInt256().ToBytes()); // update stakers list var stakers = _stakers.Get(); _stakers.Set(stakers.Concat(validatorPublicKey).ToArray()); // user to public key and public key to staker _userToPubKey.SetValue(validatorAddress, validatorPublicKey); _pubKeyToStaker.SetValue(validatorPublicKey, stakerAddress); // set start cycle _userToStartCycle.SetValue(validatorAddress, BitConverter.GetBytes(0)); } _stateManager.Approve(); // emulate and execute the genesis block var(error, removeTransactions, stateHash, relayTransactions) = Emulate(genesisBlock.Block, genesisBlock.Transactions); if (error != OperatingError.Ok) { throw new InvalidBlockException(error); } if (removeTransactions.Count != 0) { throw new InvalidBlockException(OperatingError.InvalidTransaction); } if (relayTransactions.Count != 0) { throw new InvalidBlockException(OperatingError.InvalidTransaction); } genesisBlock.Block.Header.StateHash = stateHash; genesisBlock.Block.Hash = genesisBlock.Block.Header.Keccak(); error = Execute(genesisBlock.Block, genesisBlock.Transactions, commit: true, checkStateHash: true); if (error != OperatingError.Ok) { throw new InvalidBlockException(error); } _stateManager.Commit(); BlockPersisted(genesisBlock.Block); return(true); }