Skip to content

Commit

Permalink
HIP-30: Shard reduction (#4498)
Browse files Browse the repository at this point in the history
* 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 <[email protected]>
  • Loading branch information
MaxMustermann2 and ONECasey authored Sep 11, 2023
1 parent 14eba6e commit 115e434
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 11 deletions.
22 changes: 17 additions & 5 deletions core/state_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down Expand Up @@ -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())
Expand Down Expand Up @@ -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
Expand Down
4 changes: 3 additions & 1 deletion internal/chain/reward.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 0 additions & 1 deletion internal/configs/sharding/testnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion node/node_newblock.go
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
6 changes: 3 additions & 3 deletions node/worker/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
Expand Down
7 changes: 7 additions & 0 deletions staking/reward/values.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down

0 comments on commit 115e434

Please sign in to comment.