github.com/iotexproject/iotex-core@v1.14.1-rc1/blockchain/genesis/genesis.go (about) 1 // Copyright (c) 2024 IoTeX Foundation 2 // This source code is provided 'as is' and no warranties are given as to title or non-infringement, merchantability 3 // or fitness for purpose and, to the extent permitted by law, all liability for your use of the code is disclaimed. 4 // This source code is governed by Apache License 2.0 that can be found in the LICENSE file. 5 6 package genesis 7 8 import ( 9 "math" 10 "math/big" 11 "sort" 12 "sync" 13 "sync/atomic" 14 "time" 15 16 "github.com/ethereum/go-ethereum/common" 17 "github.com/pkg/errors" 18 "go.uber.org/config" 19 "go.uber.org/zap" 20 "google.golang.org/protobuf/proto" 21 22 "github.com/iotexproject/go-pkgs/hash" 23 "github.com/iotexproject/iotex-address/address" 24 "github.com/iotexproject/iotex-proto/golang/iotextypes" 25 26 "github.com/iotexproject/iotex-core/pkg/log" 27 "github.com/iotexproject/iotex-core/pkg/unit" 28 "github.com/iotexproject/iotex-core/test/identityset" 29 ) 30 31 var ( 32 // Default contains the default genesis config 33 Default = defaultConfig() 34 35 _genesisTs int64 36 _loadGenesisTs sync.Once 37 ) 38 39 func init() { 40 initTestDefaultConfig(&Default) 41 } 42 43 func defaultConfig() Genesis { 44 return Genesis{ 45 Blockchain: Blockchain{ 46 Timestamp: 1546329600, 47 BlockGasLimit: 20000000, 48 TsunamiBlockGasLimit: 50000000, 49 ActionGasLimit: 5000000, 50 BlockInterval: 10 * time.Second, 51 NumSubEpochs: 2, 52 DardanellesNumSubEpochs: 30, 53 NumDelegates: 24, 54 NumCandidateDelegates: 36, 55 TimeBasedRotation: false, 56 PacificBlockHeight: 432001, 57 AleutianBlockHeight: 864001, 58 BeringBlockHeight: 1512001, 59 CookBlockHeight: 1641601, 60 DardanellesBlockHeight: 1816201, 61 DaytonaBlockHeight: 3238921, 62 EasterBlockHeight: 4478761, 63 FbkMigrationBlockHeight: 5157001, 64 FairbankBlockHeight: 5165641, 65 GreenlandBlockHeight: 6544441, 66 HawaiiBlockHeight: 11267641, 67 IcelandBlockHeight: 12289321, 68 JutlandBlockHeight: 13685401, 69 KamchatkaBlockHeight: 13816441, 70 LordHoweBlockHeight: 13979161, 71 MidwayBlockHeight: 16509241, 72 NewfoundlandBlockHeight: 17662681, 73 OkhotskBlockHeight: 21542761, 74 PalauBlockHeight: 22991401, 75 QuebecBlockHeight: 24838201, 76 RedseaBlockHeight: 26704441, 77 SumatraBlockHeight: 28516681, 78 TsunamiBlockHeight: 29275561, 79 ToBeEnabledBlockHeight: math.MaxUint64, 80 }, 81 Account: Account{ 82 InitBalanceMap: make(map[string]string), 83 ReplayDeployerWhitelist: []string{"0x3fab184622dc19b6109349b94811493bf2a45362"}, 84 }, 85 Poll: Poll{ 86 PollMode: "nativeMix", 87 EnableGravityChainVoting: true, 88 GravityChainCeilingHeight: 10199000, 89 ProbationEpochPeriod: 6, 90 ProbationIntensityRate: 90, 91 UnproductiveDelegateMaxCacheSize: 20, 92 SystemStakingContractAddress: "io1drde9f483guaetl3w3w6n6y7yv80f8fael7qme", // https://iotexscout.io/tx/8b899515d180d631abe8596b091380b0f42117122415393fa459c74c2bc5b6af 93 SystemStakingContractHeight: 24486464, 94 }, 95 Rewarding: Rewarding{ 96 InitBalanceStr: unit.ConvertIotxToRau(200000000).String(), 97 BlockRewardStr: unit.ConvertIotxToRau(16).String(), 98 DardanellesBlockRewardStr: unit.ConvertIotxToRau(8).String(), 99 EpochRewardStr: unit.ConvertIotxToRau(12500).String(), 100 AleutianEpochRewardStr: unit.ConvertIotxToRau(18750).String(), 101 NumDelegatesForEpochReward: 100, 102 ExemptAddrStrsFromEpochReward: []string{}, 103 FoundationBonusStr: unit.ConvertIotxToRau(80).String(), 104 NumDelegatesForFoundationBonus: 36, 105 FoundationBonusLastEpoch: 8760, 106 FoundationBonusP2StartEpoch: 9698, 107 FoundationBonusP2EndEpoch: 18458, 108 }, 109 Staking: Staking{ 110 VoteWeightCalConsts: VoteWeightCalConsts{ 111 DurationLg: 1.2, 112 AutoStake: 1, 113 SelfStake: 1.06, 114 }, 115 RegistrationConsts: RegistrationConsts{ 116 Fee: unit.ConvertIotxToRau(100).String(), 117 MinSelfStake: unit.ConvertIotxToRau(1200000).String(), 118 }, 119 WithdrawWaitingPeriod: 3 * 24 * time.Hour, 120 MinStakeAmount: unit.ConvertIotxToRau(100).String(), 121 BootstrapCandidates: []BootstrapCandidate{}, 122 EndorsementWithdrawWaitingBlocks: 24 * 60 * 60 / 5, 123 }, 124 } 125 } 126 127 // TestDefault is the default genesis config for testing 128 func TestDefault() Genesis { 129 ge := defaultConfig() 130 initTestDefaultConfig(&ge) 131 return ge 132 } 133 134 func initTestDefaultConfig(cfg *Genesis) { 135 cfg.PacificBlockHeight = 0 136 for i := 0; i < identityset.Size(); i++ { 137 addr := identityset.Address(i).String() 138 value := unit.ConvertIotxToRau(100000000).String() 139 cfg.InitBalanceMap[addr] = value 140 if uint64(i) < cfg.NumDelegates { 141 cfg.Delegates = append(cfg.Delegates, Delegate{ 142 OperatorAddrStr: addr, 143 RewardAddrStr: addr, 144 VotesStr: value, 145 }) 146 } 147 } 148 } 149 150 type ( 151 // Genesis is the root level of genesis config. Genesis config is the network-wide blockchain config. All the nodes 152 // participating into the same network should use EXACTLY SAME genesis config. 153 Genesis struct { 154 Blockchain `yaml:"blockchain"` 155 Account `yaml:"account"` 156 Poll `yaml:"poll"` 157 Rewarding `yaml:"rewarding"` 158 Staking `yaml:"staking"` 159 } 160 // Blockchain contains blockchain level configs 161 Blockchain struct { 162 // Timestamp is the timestamp of the genesis block 163 Timestamp int64 164 // BlockGasLimit is the total gas limit could be consumed in a block 165 BlockGasLimit uint64 `yaml:"blockGasLimit"` 166 // TsunamiBlockGasLimit is the block gas limit starting Tsunami height (raised to 50M by default) 167 TsunamiBlockGasLimit uint64 `yaml:"tsunamiBlockGasLimit"` 168 // ActionGasLimit is the per action gas limit cap 169 ActionGasLimit uint64 `yaml:"actionGasLimit"` 170 // BlockInterval is the interval between two blocks 171 BlockInterval time.Duration `yaml:"blockInterval"` 172 // NumSubEpochs is the number of sub epochs in one epoch of block production 173 NumSubEpochs uint64 `yaml:"numSubEpochs"` 174 // DardanellesNumSubEpochs is the number of sub epochs starts from dardanelles height in one epoch of block production 175 DardanellesNumSubEpochs uint64 `yaml:"dardanellesNumSubEpochs"` 176 // NumDelegates is the number of delegates that participate into one epoch of block production 177 NumDelegates uint64 `yaml:"numDelegates"` 178 // NumCandidateDelegates is the number of candidate delegates, who may be selected as a delegate via roll dpos 179 NumCandidateDelegates uint64 `yaml:"numCandidateDelegates"` 180 // TimeBasedRotation is the flag to enable rotating delegates' time slots on a block height 181 TimeBasedRotation bool `yaml:"timeBasedRotation"` 182 // PacificBlockHeight is the start height of using the logic of Pacific version 183 // TODO: PacificBlockHeight is not added into protobuf definition for backward compatibility 184 PacificBlockHeight uint64 `yaml:"pacificHeight"` 185 // AleutianBlockHeight is the start height of adding bloom filter of all events into block header 186 AleutianBlockHeight uint64 `yaml:"aleutianHeight"` 187 // BeringBlockHeight is the start height of evm upgrade 188 BeringBlockHeight uint64 `yaml:"beringHeight"` 189 // CookBlockHeight is the start height of native staking 190 CookBlockHeight uint64 `yaml:"cookHeight"` 191 // DardanellesBlockHeight is the start height of 5s block internal 192 DardanellesBlockHeight uint64 `yaml:"dardanellesHeight"` 193 // DaytonaBlockHeight is the height to fix low gas for read native staking contract 194 DaytonaBlockHeight uint64 `yaml:"daytonaBlockHeight"` 195 // EasterBlockHeight is the start height of probation for slashing 196 EasterBlockHeight uint64 `yaml:"easterHeight"` 197 // FbkMigrationBlockHeight is the start height for fairbank migration 198 FbkMigrationBlockHeight uint64 `yaml:"fbkMigrationHeight"` 199 // FairbankBlockHeight is the start height to switch to native staking V2 200 FairbankBlockHeight uint64 `yaml:"fairbankHeight"` 201 // GreenlandBlockHeight is the start height of storing latest 720 block meta and rewarding/staking bucket pool 202 GreenlandBlockHeight uint64 `yaml:"greenlandHeight"` 203 // HawaiiBlockHeight is the start height to 204 // 1. fix GetBlockHash in EVM 205 // 2. add revert message to log 206 // 3. fix change to same candidate in staking protocol 207 // 4. fix sorted map in StateDBAdapter 208 // 5. use pending nonce in EVM 209 HawaiiBlockHeight uint64 `yaml:"hawaiiHeight"` 210 // IcelandBlockHeight is the start height to support chainID opcode and EVM Istanbul 211 IcelandBlockHeight uint64 `yaml:"icelandHeight"` 212 // JutlandBlockHeight is the start height to 213 // 1. report more EVM error codes 214 // 2. enable the opCall fix 215 JutlandBlockHeight uint64 `yaml:"jutlandHeight"` 216 // KamchatkaBlockHeight is the start height to 217 // 1. fix EVM snapshot order 218 // 2. extend foundation bonus 219 KamchatkaBlockHeight uint64 `yaml:"kamchatkaHeight"` 220 // LordHoweBlockHeight is the start height to 221 // 1. recover the smart contracts affected by snapshot order 222 // 2. clear snapshots in Revert() 223 LordHoweBlockHeight uint64 `yaml:"lordHoweHeight"` 224 // MidwayBlockHeight is the start height to 225 // 1. allow correct and default ChainID 226 // 2. fix GetHashFunc in EVM 227 // 3. correct tx/log index for transaction receipt and EVM log 228 // 4. revert logs upon tx reversion in EVM 229 MidwayBlockHeight uint64 `yaml:"midwayHeight"` 230 // NewfoundlandBlockHeight is the start height to 231 // 1. use correct chainID 232 // 2. check legacy address 233 // 3. enable web3 staking transaction 234 NewfoundlandBlockHeight uint64 `yaml:"newfoundlandHeight"` 235 // OkhotskBlockHeight is the start height to 236 // 1. enable London EVM 237 // 2. create zero-nonce account 238 // 3. fix gas and nonce update 239 // 4. fix unproductive delegates in staking protocol 240 OkhotskBlockHeight uint64 `yaml:"okhotskHeight"` 241 // PalauBlockHeight is the the start height to 242 // 1. enable rewarding action via web3 243 // 2. broadcast node info into the p2p network 244 PalauBlockHeight uint64 `yaml:"palauHeight"` 245 // QuebecBlockHeight is the start height to 246 // 1. enforce using correct chainID only 247 // 2. enable IIP-13 liquidity staking 248 // 3. valiate system action layout 249 QuebecBlockHeight uint64 `yaml:"quebecHeight"` 250 // RedseaBlockHeight is the start height to 251 // 1. upgrade go-ethereum to Bellatrix release 252 // 2. correct weighted votes for contract staking bucket 253 RedseaBlockHeight uint64 `yaml:"redseaHeight"` 254 // SumatraBlockHeight is the start height to enable Shanghai EVM 255 SumatraBlockHeight uint64 `yaml:"sumatraHeight"` 256 // TsunamiBlockHeight is the start height to 257 // 1. enable delegate endorsement 258 // 2. generate transaction log for Suicide() call in EVM 259 // 3. raise block gas limit to 50M 260 TsunamiBlockHeight uint64 `yaml:"tsunamiHeight"` 261 // ToBeEnabledBlockHeight is a fake height that acts as a gating factor for WIP features 262 // upon next release, change IsToBeEnabled() to IsNextHeight() for features to be released 263 ToBeEnabledBlockHeight uint64 `yaml:"toBeEnabledHeight"` 264 } 265 // Account contains the configs for account protocol 266 Account struct { 267 // InitBalanceMap is the address and initial balance mapping before the first block. 268 InitBalanceMap map[string]string `yaml:"initBalances"` 269 // ReplayDeployerWhitelist is the whitelist address for unprotected (pre-EIP155) transaction 270 ReplayDeployerWhitelist []string `yaml:"replayDeployerWhitelist"` 271 } 272 // Poll contains the configs for poll protocol 273 Poll struct { 274 // PollMode is different based on chain type or poll input data source 275 PollMode string `yaml:"pollMode"` 276 // EnableGravityChainVoting is a flag whether read voting from gravity chain 277 EnableGravityChainVoting bool `yaml:"enableGravityChainVoting"` 278 // GravityChainStartHeight is the height in gravity chain where the init poll result stored 279 GravityChainStartHeight uint64 `yaml:"gravityChainStartHeight"` 280 // GravityChainCeilingHeight is the height in gravity chain where the poll is no longer needed 281 GravityChainCeilingHeight uint64 `yaml:"gravityChainCeilingHeight"` 282 // GravityChainHeightInterval the height interval on gravity chain to pull delegate information 283 GravityChainHeightInterval uint64 `yaml:"gravityChainHeightInterval"` 284 // RegisterContractAddress is the address of register contract 285 RegisterContractAddress string `yaml:"registerContractAddress"` 286 // StakingContractAddress is the address of staking contract 287 StakingContractAddress string `yaml:"stakingContractAddress"` 288 // NativeStakingContractAddress is the address of native staking contract 289 NativeStakingContractAddress string `yaml:"nativeStakingContractAddress"` 290 // NativeStakingContractCode is the code of native staking contract 291 NativeStakingContractCode string `yaml:"nativeStakingContractCode"` 292 // ConsortiumCommitteeCode is the code of consortiumCommittee contract 293 ConsortiumCommitteeContractCode string `yaml:"consortiumCommitteeContractCode"` 294 // VoteThreshold is the vote threshold amount in decimal string format 295 VoteThreshold string `yaml:"voteThreshold"` 296 // ScoreThreshold is the score threshold amount in decimal string format 297 ScoreThreshold string `yaml:"scoreThreshold"` 298 // SelfStakingThreshold is self-staking vote threshold amount in decimal string format 299 SelfStakingThreshold string `yaml:"selfStakingThreshold"` 300 // Delegates is a list of delegates with votes 301 Delegates []Delegate `yaml:"delegates"` 302 // ProbationEpochPeriod is a duration of probation after delegate's productivity is lower than threshold 303 ProbationEpochPeriod uint64 `yaml:"probationEpochPeriod"` 304 // ProbationIntensityRate is a intensity rate of probation range from [0, 100], where 100 is hard-probation 305 ProbationIntensityRate uint32 `yaml:"probationIntensityRate"` 306 // UnproductiveDelegateMaxCacheSize is a max cache size of upd which is stored into state DB (probationEpochPeriod <= UnproductiveDelegateMaxCacheSize) 307 UnproductiveDelegateMaxCacheSize uint64 `yaml:"unproductiveDelegateMaxCacheSize"` 308 // SystemStakingContractAddress is the address of system staking contract 309 SystemStakingContractAddress string `yaml:"systemStakingContractAddress"` 310 // SystemStakingContractHeight is the height of system staking contract 311 SystemStakingContractHeight uint64 `yaml:"systemStakingContractHeight"` 312 // SystemSGDContractAddress is the address of system sgd contract 313 SystemSGDContractAddress string `yaml:"systemSGDContractAddress"` 314 // SystemSGDContractHeight is the height of system sgd contract 315 SystemSGDContractHeight uint64 `yaml:"systemSGDContractHeight"` 316 } 317 // Delegate defines a delegate with address and votes 318 Delegate struct { 319 // OperatorAddrStr is the address who will operate the node 320 OperatorAddrStr string `yaml:"operatorAddr"` 321 // RewardAddrStr is the address who will get the reward when operator produces blocks 322 RewardAddrStr string `yaml:"rewardAddr"` 323 // VotesStr is the score for the operator to rank and weight for rewardee to split epoch reward 324 VotesStr string `yaml:"votes"` 325 } 326 // Rewarding contains the configs for rewarding protocol 327 Rewarding struct { 328 // InitBalanceStr is the initial balance of the rewarding protocol in decimal string format 329 InitBalanceStr string `yaml:"initBalance"` 330 // BlockReward is the block reward amount in decimal string format 331 BlockRewardStr string `yaml:"blockReward"` 332 // DardanellesBlockReward is the block reward amount starts from dardanelles height in decimal string format 333 DardanellesBlockRewardStr string `yaml:"dardanellesBlockReward"` 334 // EpochReward is the epoch reward amount in decimal string format 335 EpochRewardStr string `yaml:"epochReward"` 336 // AleutianEpochRewardStr is the epoch reward amount in decimal string format after aleutian fork 337 AleutianEpochRewardStr string `yaml:"aleutianEpochReward"` 338 // NumDelegatesForEpochReward is the number of top candidates that will share a epoch reward 339 NumDelegatesForEpochReward uint64 `yaml:"numDelegatesForEpochReward"` 340 // ExemptAddrStrsFromEpochReward is the list of addresses in encoded string format that exempt from epoch reward 341 ExemptAddrStrsFromEpochReward []string `yaml:"exemptAddrsFromEpochReward"` 342 // FoundationBonusStr is the bootstrap bonus in decimal string format 343 FoundationBonusStr string `yaml:"foundationBonus"` 344 // NumDelegatesForFoundationBonus is the number of top candidate that will get the bootstrap bonus 345 NumDelegatesForFoundationBonus uint64 `yaml:"numDelegatesForFoundationBonus"` 346 // FoundationBonusLastEpoch is the last epoch number that bootstrap bonus will be granted 347 FoundationBonusLastEpoch uint64 `yaml:"foundationBonusLastEpoch"` 348 // FoundationBonusP2StartEpoch is the start epoch number for part 2 foundation bonus 349 FoundationBonusP2StartEpoch uint64 `yaml:"foundationBonusP2StartEpoch"` 350 // FoundationBonusP2EndEpoch is the end epoch number for part 2 foundation bonus 351 FoundationBonusP2EndEpoch uint64 `yaml:"foundationBonusP2EndEpoch"` 352 // ProductivityThreshold is the percentage number that a delegate's productivity needs to reach not to get probation 353 ProductivityThreshold uint64 `yaml:"productivityThreshold"` 354 } 355 // Staking contains the configs for staking protocol 356 Staking struct { 357 VoteWeightCalConsts VoteWeightCalConsts `yaml:"voteWeightCalConsts"` 358 RegistrationConsts RegistrationConsts `yaml:"registrationConsts"` 359 WithdrawWaitingPeriod time.Duration `yaml:"withdrawWaitingPeriod"` 360 MinStakeAmount string `yaml:"minStakeAmount"` 361 BootstrapCandidates []BootstrapCandidate `yaml:"bootstrapCandidates"` 362 EndorsementWithdrawWaitingBlocks uint64 `yaml:"endorsementWithdrawWaitingBlocks"` 363 } 364 365 // VoteWeightCalConsts contains the configs for calculating vote weight 366 VoteWeightCalConsts struct { 367 DurationLg float64 `yaml:"durationLg"` 368 AutoStake float64 `yaml:"autoStake"` 369 SelfStake float64 `yaml:"selfStake"` 370 } 371 372 // RegistrationConsts contains the configs for candidate registration 373 RegistrationConsts struct { 374 Fee string `yaml:"fee"` 375 MinSelfStake string `yaml:"minSelfStake"` 376 } 377 378 // BootstrapCandidate is the candidate data need to be provided to bootstrap candidate. 379 BootstrapCandidate struct { 380 OwnerAddress string `yaml:"ownerAddress"` 381 OperatorAddress string `yaml:"operatorAddress"` 382 RewardAddress string `yaml:"rewardAddress"` 383 Name string `yaml:"name"` 384 SelfStakingTokens string `yaml:"selfStakingTokens"` 385 } 386 ) 387 388 // New constructs a genesis config. It loads the default values, and could be overwritten by values defined in the yaml 389 // config files 390 func New(genesisPath string) (Genesis, error) { 391 def := defaultConfig() 392 393 opts := make([]config.YAMLOption, 0) 394 opts = append(opts, config.Static(def)) 395 if genesisPath != "" { 396 opts = append(opts, config.File(genesisPath)) 397 } 398 yaml, err := config.NewYAML(opts...) 399 if err != nil { 400 return Genesis{}, errors.Wrap(err, "error when constructing a genesis in yaml") 401 } 402 403 var genesis Genesis 404 if err := yaml.Get(config.Root).Populate(&genesis); err != nil { 405 return Genesis{}, errors.Wrap(err, "failed to unmarshal yaml genesis to struct") 406 } 407 return genesis, nil 408 } 409 410 // SetGenesisTimestamp sets the genesis timestamp 411 func SetGenesisTimestamp(ts int64) { 412 _loadGenesisTs.Do(func() { 413 _genesisTs = ts 414 }) 415 } 416 417 // Timestamp returns the genesis timestamp 418 func Timestamp() int64 { 419 return atomic.LoadInt64(&_genesisTs) 420 } 421 422 // Hash is the hash of genesis config 423 func (g *Genesis) Hash() hash.Hash256 { 424 gbProto := iotextypes.GenesisBlockchain{ 425 Timestamp: g.Timestamp, 426 BlockGasLimit: g.BlockGasLimit, 427 ActionGasLimit: g.ActionGasLimit, 428 BlockInterval: g.BlockInterval.Nanoseconds(), 429 NumSubEpochs: g.NumSubEpochs, 430 NumDelegates: g.NumDelegates, 431 NumCandidateDelegates: g.NumCandidateDelegates, 432 TimeBasedRotation: g.TimeBasedRotation, 433 } 434 435 initBalanceAddrs := make([]string, 0) 436 for initBalanceAddr := range g.InitBalanceMap { 437 initBalanceAddrs = append(initBalanceAddrs, initBalanceAddr) 438 } 439 sort.Strings(initBalanceAddrs) 440 initBalances := make([]string, 0) 441 for _, initBalanceAddr := range initBalanceAddrs { 442 initBalances = append(initBalances, g.InitBalanceMap[initBalanceAddr]) 443 } 444 aProto := iotextypes.GenesisAccount{ 445 InitBalanceAddrs: initBalanceAddrs, 446 InitBalances: initBalances, 447 } 448 449 dProtos := make([]*iotextypes.GenesisDelegate, 0) 450 for _, d := range g.Delegates { 451 dProto := iotextypes.GenesisDelegate{ 452 OperatorAddr: d.OperatorAddrStr, 453 RewardAddr: d.RewardAddrStr, 454 Votes: d.VotesStr, 455 } 456 dProtos = append(dProtos, &dProto) 457 } 458 pProto := iotextypes.GenesisPoll{ 459 EnableGravityChainVoting: g.EnableGravityChainVoting, 460 GravityChainStartHeight: g.GravityChainStartHeight, 461 RegisterContractAddress: g.RegisterContractAddress, 462 StakingContractAddress: g.StakingContractAddress, 463 VoteThreshold: g.VoteThreshold, 464 ScoreThreshold: g.ScoreThreshold, 465 SelfStakingThreshold: g.SelfStakingThreshold, 466 Delegates: dProtos, 467 } 468 469 rProto := iotextypes.GenesisRewarding{ 470 InitBalance: g.InitBalanceStr, 471 BlockReward: g.BlockRewardStr, 472 EpochReward: g.EpochRewardStr, 473 NumDelegatesForEpochReward: g.NumDelegatesForEpochReward, 474 FoundationBonus: g.FoundationBonusStr, 475 NumDelegatesForFoundationBonus: g.NumDelegatesForFoundationBonus, 476 FoundationBonusLastEpoch: g.FoundationBonusLastEpoch, 477 ProductivityThreshold: g.ProductivityThreshold, 478 } 479 480 gProto := iotextypes.Genesis{ 481 Blockchain: &gbProto, 482 Account: &aProto, 483 Poll: &pProto, 484 Rewarding: &rProto, 485 } 486 b, err := proto.Marshal(&gProto) 487 if err != nil { 488 log.L().Panic("Error when marshaling genesis proto", zap.Error(err)) 489 } 490 return hash.Hash256b(b) 491 } 492 493 func (g *Blockchain) isPost(targetHeight, height uint64) bool { 494 return height >= targetHeight 495 } 496 497 // IsPacific checks whether height is equal to or larger than pacific height 498 func (g *Blockchain) IsPacific(height uint64) bool { 499 return g.isPost(g.PacificBlockHeight, height) 500 } 501 502 // IsAleutian checks whether height is equal to or larger than aleutian height 503 func (g *Blockchain) IsAleutian(height uint64) bool { 504 return g.isPost(g.AleutianBlockHeight, height) 505 } 506 507 // IsBering checks whether height is equal to or larger than bering height 508 func (g *Blockchain) IsBering(height uint64) bool { 509 return g.isPost(g.BeringBlockHeight, height) 510 } 511 512 // IsCook checks whether height is equal to or larger than cook height 513 func (g *Blockchain) IsCook(height uint64) bool { 514 return g.isPost(g.CookBlockHeight, height) 515 } 516 517 // IsDardanelles checks whether height is equal to or larger than dardanelles height 518 func (g *Blockchain) IsDardanelles(height uint64) bool { 519 return g.isPost(g.DardanellesBlockHeight, height) 520 } 521 522 // IsDaytona checks whether height is equal to or larger than daytona height 523 func (g *Blockchain) IsDaytona(height uint64) bool { 524 return g.isPost(g.DaytonaBlockHeight, height) 525 } 526 527 // IsEaster checks whether height is equal to or larger than easter height 528 func (g *Blockchain) IsEaster(height uint64) bool { 529 return g.isPost(g.EasterBlockHeight, height) 530 } 531 532 // IsFairbank checks whether height is equal to or larger than fairbank height 533 func (g *Blockchain) IsFairbank(height uint64) bool { 534 return g.isPost(g.FairbankBlockHeight, height) 535 } 536 537 // IsFbkMigration checks whether height is equal to or larger than fbk migration height 538 func (g *Blockchain) IsFbkMigration(height uint64) bool { 539 return g.isPost(g.FbkMigrationBlockHeight, height) 540 } 541 542 // IsGreenland checks whether height is equal to or larger than greenland height 543 func (g *Blockchain) IsGreenland(height uint64) bool { 544 return g.isPost(g.GreenlandBlockHeight, height) 545 } 546 547 // IsHawaii checks whether height is equal to or larger than hawaii height 548 func (g *Blockchain) IsHawaii(height uint64) bool { 549 return g.isPost(g.HawaiiBlockHeight, height) 550 } 551 552 // IsIceland checks whether height is equal to or larger than iceland height 553 func (g *Blockchain) IsIceland(height uint64) bool { 554 return g.isPost(g.IcelandBlockHeight, height) 555 } 556 557 // IsJutland checks whether height is equal to or larger than jutland height 558 func (g *Blockchain) IsJutland(height uint64) bool { 559 return g.isPost(g.JutlandBlockHeight, height) 560 } 561 562 // IsKamchatka checks whether height is equal to or larger than kamchatka height 563 func (g *Blockchain) IsKamchatka(height uint64) bool { 564 return g.isPost(g.KamchatkaBlockHeight, height) 565 } 566 567 // IsLordHowe checks whether height is equal to or larger than lordHowe height 568 func (g *Blockchain) IsLordHowe(height uint64) bool { 569 return g.isPost(g.LordHoweBlockHeight, height) 570 } 571 572 // IsMidway checks whether height is equal to or larger than midway height 573 func (g *Blockchain) IsMidway(height uint64) bool { 574 return g.isPost(g.MidwayBlockHeight, height) 575 } 576 577 // IsNewfoundland checks whether height is equal to or larger than newfoundland height 578 func (g *Blockchain) IsNewfoundland(height uint64) bool { 579 return g.isPost(g.NewfoundlandBlockHeight, height) 580 } 581 582 // IsOkhotsk checks whether height is equal to or larger than okhotsk height 583 func (g *Blockchain) IsOkhotsk(height uint64) bool { 584 return g.isPost(g.OkhotskBlockHeight, height) 585 } 586 587 // IsPalau checks whether height is equal to or larger than palau height 588 func (g *Blockchain) IsPalau(height uint64) bool { 589 return g.isPost(g.PalauBlockHeight, height) 590 } 591 592 // IsQuebec checks whether height is equal to or larger than quebec height 593 func (g *Blockchain) IsQuebec(height uint64) bool { 594 return g.isPost(g.QuebecBlockHeight, height) 595 } 596 597 // IsRedsea checks whether height is equal to or larger than redsea height 598 func (g *Blockchain) IsRedsea(height uint64) bool { 599 return g.isPost(g.RedseaBlockHeight, height) 600 } 601 602 // IsSumatra checks whether height is equal to or larger than sumatra height 603 func (g *Blockchain) IsSumatra(height uint64) bool { 604 return g.isPost(g.SumatraBlockHeight, height) 605 } 606 607 // IsTsunami checks whether height is equal to or larger than tsunami height 608 func (g *Blockchain) IsTsunami(height uint64) bool { 609 return g.isPost(g.TsunamiBlockHeight, height) 610 } 611 612 // IsToBeEnabled checks whether height is equal to or larger than toBeEnabled height 613 func (g *Blockchain) IsToBeEnabled(height uint64) bool { 614 return g.isPost(g.ToBeEnabledBlockHeight, height) 615 } 616 617 func (g *Blockchain) BlockGasLimitByHeight(height uint64) uint64 { 618 if g.isPost(g.TsunamiBlockHeight, height) { 619 // block gas limit raised to 50M after Tsunami block height 620 return g.TsunamiBlockGasLimit 621 } 622 return g.BlockGasLimit 623 } 624 625 // IsDeployerWhitelisted returns if the replay deployer is whitelisted 626 func (a *Account) IsDeployerWhitelisted(deployer address.Address) bool { 627 for _, v := range a.ReplayDeployerWhitelist { 628 if v[:3] == "io1" { 629 if addr, err := address.FromString(v); err == nil { 630 if address.Equal(deployer, addr) { 631 return true 632 } 633 } 634 } else if common.IsHexAddress(v) { 635 if addr, err := address.FromHex(v); err == nil { 636 if address.Equal(deployer, addr) { 637 return true 638 } 639 } 640 } 641 } 642 return false 643 } 644 645 // InitBalances returns the address that have initial balances and the corresponding amounts. The i-th amount is the 646 // i-th address' balance. 647 func (a *Account) InitBalances() ([]address.Address, []*big.Int) { 648 // Make the list always be ordered 649 addrStrs := make([]string, 0) 650 for addrStr := range a.InitBalanceMap { 651 addrStrs = append(addrStrs, addrStr) 652 } 653 sort.Strings(addrStrs) 654 addrs := make([]address.Address, 0) 655 amounts := make([]*big.Int, 0) 656 for _, addrStr := range addrStrs { 657 addr, err := address.FromString(addrStr) 658 if err != nil { 659 log.L().Panic("Error when decoding the account protocol init balance address from string.", zap.Error(err)) 660 } 661 addrs = append(addrs, addr) 662 amount, ok := new(big.Int).SetString(a.InitBalanceMap[addrStr], 10) 663 if !ok { 664 log.S().Panicf("Error when casting init balance string %s into big int", a.InitBalanceMap[addrStr]) 665 } 666 amounts = append(amounts, amount) 667 } 668 return addrs, amounts 669 } 670 671 // OperatorAddr is the address of operator 672 func (d *Delegate) OperatorAddr() address.Address { 673 addr, err := address.FromString(d.OperatorAddrStr) 674 if err != nil { 675 log.L().Panic("Error when decoding the poll protocol operator address from string.", zap.Error(err)) 676 } 677 return addr 678 } 679 680 // RewardAddr is the address of rewardee, which is allowed to be nil 681 func (d *Delegate) RewardAddr() address.Address { 682 if d.RewardAddrStr == "" { 683 return nil 684 } 685 addr, err := address.FromString(d.RewardAddrStr) 686 if err != nil { 687 log.L().Panic("Error when decoding the poll protocol rewardee address from string.", zap.Error(err)) 688 } 689 return addr 690 } 691 692 // Votes returns the votes 693 func (d *Delegate) Votes() *big.Int { 694 val, ok := new(big.Int).SetString(d.VotesStr, 10) 695 if !ok { 696 log.S().Panicf("Error when casting votes string %s into big int", d.VotesStr) 697 } 698 return val 699 } 700 701 // InitBalance returns the init balance of the rewarding fund 702 func (r *Rewarding) InitBalance() *big.Int { 703 val, ok := new(big.Int).SetString(r.InitBalanceStr, 10) 704 if !ok { 705 log.S().Panicf("Error when casting init balance string %s into big int", r.InitBalanceStr) 706 } 707 return val 708 } 709 710 // BlockReward returns the block reward amount 711 func (r *Rewarding) BlockReward() *big.Int { 712 val, ok := new(big.Int).SetString(r.BlockRewardStr, 10) 713 if !ok { 714 log.S().Panicf("Error when casting block reward string %s into big int", r.BlockRewardStr) 715 } 716 return val 717 } 718 719 // EpochReward returns the epoch reward amount 720 func (r *Rewarding) EpochReward() *big.Int { 721 val, ok := new(big.Int).SetString(r.EpochRewardStr, 10) 722 if !ok { 723 log.S().Panicf("Error when casting epoch reward string %s into big int", r.EpochRewardStr) 724 } 725 return val 726 } 727 728 // AleutianEpochReward returns the epoch reward amount after Aleutian fork 729 func (r *Rewarding) AleutianEpochReward() *big.Int { 730 val, ok := new(big.Int).SetString(r.AleutianEpochRewardStr, 10) 731 if !ok { 732 log.S().Panicf("Error when casting epoch reward string %s into big int", r.EpochRewardStr) 733 } 734 return val 735 } 736 737 // DardanellesBlockReward returns the block reward amount after dardanelles fork 738 func (r *Rewarding) DardanellesBlockReward() *big.Int { 739 val, ok := new(big.Int).SetString(r.DardanellesBlockRewardStr, 10) 740 if !ok { 741 log.S().Panicf("Error when casting block reward string %s into big int", r.EpochRewardStr) 742 } 743 return val 744 } 745 746 // ExemptAddrsFromEpochReward returns the list of addresses that exempt from epoch reward 747 func (r *Rewarding) ExemptAddrsFromEpochReward() []address.Address { 748 addrs := make([]address.Address, 0) 749 for _, addrStr := range r.ExemptAddrStrsFromEpochReward { 750 addr, err := address.FromString(addrStr) 751 if err != nil { 752 log.L().Panic("Error when decoding the rewarding protocol exempt address from string.", zap.Error(err)) 753 } 754 addrs = append(addrs, addr) 755 } 756 return addrs 757 } 758 759 // FoundationBonus returns the bootstrap bonus amount rewarded per epoch 760 func (r *Rewarding) FoundationBonus() *big.Int { 761 val, ok := new(big.Int).SetString(r.FoundationBonusStr, 10) 762 if !ok { 763 log.S().Panicf("Error when casting bootstrap bonus string %s into big int", r.EpochRewardStr) 764 } 765 return val 766 }