From 115e434f73308cfa92e41d7c854390e6285efeaa Mon Sep 17 00:00:00 2001 From: Max <82761650+MaxMustermann2@users.noreply.github.com> Date: Mon, 11 Sep 2023 18:58:11 +0000 Subject: [PATCH] HIP-30: Shard reduction (#4498) * HIP-30: sharding configuration boilerplate * update comments * goimports * HIP-30: minimum validator commission of 7% Based on #4495, which must be merged before this PR. This PR should be rebased with dev after #4495 is merged to retain atomicity of changes by pull request. * goimports * HIP-30: Emission split implementation Note that the allocated split of the emission goes directly to the recipient (and not via the Reward). This is because rewards are indexed by validator and not by delegator, and the recipient may/may not have any delegations which we can reward. Even if one was guaranteed to exist, it would mess up the math of the validator. * set up mainnet recipient of emission split * HIP-30: Emission split addresses for non mainnet * HIP-30: deactivate shard 2 and 3 validators * update test * update test * shard reduction: update block reward --------- Co-authored-by: Casey Gardiner <117784577+ONECasey@users.noreply.github.com> --- core/state_processor.go | 22 +++++++++++++++++----- internal/chain/reward.go | 4 +++- internal/configs/sharding/testnet.go | 1 - node/node_newblock.go | 2 +- node/worker/worker.go | 6 +++--- staking/reward/values.go | 7 +++++++ 6 files changed, 31 insertions(+), 11 deletions(-) diff --git a/core/state_processor.go b/core/state_processor.go index 7a2f2a5d47..a79a966b53 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -185,7 +185,7 @@ func (p *StateProcessor) Process( } } - if err := MayTestnetShardReduction(p.bc, statedb, header); err != nil { + if err := MayShardReduction(p.bc, statedb, header); err != nil { return nil, nil, nil, nil, 0, nil, statedb, err } @@ -442,13 +442,16 @@ func StakingToMessage( return msg, nil } -// MayTestnetShardReduction handles the change in the number of Shards. It will mark the affected validator as inactive. +// MayShardReduction handles the change in the number of Shards. It will mark the affected validator as inactive. // This function does not handle all cases, only for ShardNum from 4 to 2. -func MayTestnetShardReduction(bc ChainContext, statedb *state.DB, header *block.Header) error { +func MayShardReduction(bc ChainContext, statedb *state.DB, header *block.Header) error { isBeaconChain := header.ShardID() == shard.BeaconChainShardID isLastBlock := shard.Schedule.IsLastBlock(header.Number().Uint64()) - isTestnet := nodeconfig.GetDefaultConfig().GetNetworkType() == nodeconfig.Testnet - if !(isTestnet && isBeaconChain && isLastBlock) { + networkType := nodeconfig.GetDefaultConfig().GetNetworkType() + isTestnet := networkType == nodeconfig.Testnet + isMainnet := networkType == nodeconfig.Mainnet + isReducenet := isMainnet || isTestnet + if !(isReducenet && isBeaconChain && isLastBlock) { return nil } curInstance := shard.Schedule.InstanceForEpoch(header.Epoch()) @@ -479,6 +482,15 @@ func MayTestnetShardReduction(bc ChainContext, statedb *state.DB, header *block. for _, pubKey := range validator.SlotPubKeys { curShard := new(big.Int).Mod(pubKey.Big(), big.NewInt(int64(curNumShards))).Uint64() nextShard := new(big.Int).Mod(pubKey.Big(), big.NewInt(int64(nextNumShards))).Uint64() + // background: any editValidator transactions take effect at next epoch. + // assumption: shard reduction happens at epoch X. + // validators who wish to continue validating after the shard reduction occurs + // must have a different node running with a key from shard 0 or 1. + // this key must be added to the validator during epoch X - 1 + // and keys belonging to shards 2 and 3 removed at that point in time. + // the different node running will be unelected, but continue syncing in X - 1. + // if elected, it will start validating in epoch X. + // once epoch X begins, they can terminate servers from shards 2 and 3. if curShard >= uint64(nextNumShards) || curShard != nextShard { validator.Status = effective.Inactive break diff --git a/internal/chain/reward.go b/internal/chain/reward.go index 7843380933..392cb5d790 100644 --- a/internal/chain/reward.go +++ b/internal/chain/reward.go @@ -224,7 +224,9 @@ func getDefaultStakingReward(bc engine.ChainReader, epoch *big.Int, blockNum uin } } else { // Mainnet (other nets): - if bc.Config().IsTwoSeconds(epoch) { + if bc.Config().IsHIP30(epoch) { + defaultReward = stakingReward.HIP30StakedBlocks + } else if bc.Config().IsTwoSeconds(epoch) { defaultReward = stakingReward.TwoSecStakedBlocks } else if bc.Config().IsFiveSeconds(epoch) { defaultReward = stakingReward.FiveSecStakedBlocks diff --git a/internal/configs/sharding/testnet.go b/internal/configs/sharding/testnet.go index 93daeaf61f..7c2994071c 100644 --- a/internal/configs/sharding/testnet.go +++ b/internal/configs/sharding/testnet.go @@ -161,7 +161,6 @@ var ( feeCollectorsTestnet, numeric.ZeroDec(), ethCommon.Address{}, testnetReshardingEpoch, TestnetSchedule.BlocksPerEpoch(), ) - testnetV5 = MustNewInstance( 2, 30, 8, 0.15, numeric.MustNewDecFromStr("0.90"), genesis.TNHarmonyAccountsV1, diff --git a/node/node_newblock.go b/node/node_newblock.go index 008182fbcc..97f5f7bc8b 100644 --- a/node/node_newblock.go +++ b/node/node_newblock.go @@ -265,7 +265,7 @@ func (node *Node) ProposeNewBlock(commitSigs chan []byte) (*types.Block, error) } } - node.Worker.ApplyTestnetShardReduction() + node.Worker.ApplyShardReduction() // Prepare shard state var shardState *shard.State if shardState, err = node.Blockchain().SuperCommitteeForNextEpoch( diff --git a/node/worker/worker.go b/node/worker/worker.go index 5a4234229a..845ce265a3 100644 --- a/node/worker/worker.go +++ b/node/worker/worker.go @@ -224,9 +224,9 @@ func (w *Worker) commitStakingTransaction( return nil } -// ApplyTestnetShardReduction only used to reduce shards of Testnet -func (w *Worker) ApplyTestnetShardReduction() { - core.MayTestnetShardReduction(w.chain, w.current.state, w.current.header) +// ApplyShardReduction only used to reduce shards of Testnet +func (w *Worker) ApplyShardReduction() { + core.MayShardReduction(w.chain, w.current.state, w.current.header) } var ( diff --git a/staking/reward/values.go b/staking/reward/values.go index 805c2f38fc..a8a6f9ba37 100644 --- a/staking/reward/values.go +++ b/staking/reward/values.go @@ -31,6 +31,13 @@ var ( TwoSecStakedBlocks = numeric.NewDecFromBigInt(new(big.Int).Mul( big.NewInt(7*denominations.Nano), big.NewInt(denominations.Nano), )) + // HIP30StakedBlocks is the reward received after HIP-30 goes into + // effect. It is simply double the TwoSecStakedBlocks reward, since + // the number of shards is being halved and we keep emission + // constant. + HIP30StakedBlocks = numeric.NewDecFromBigInt(new(big.Int).Mul( + big.NewInt(14*denominations.Nano), big.NewInt(denominations.Nano), + )) // TotalInitialTokens is the total amount of tokens (in ONE) at block 0 of the network. // This should be set/change on the node's init according to the core.GenesisSpec.