mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2024-12-21 19:20:38 +00:00
Add PulseChain burn
This commit is contained in:
parent
20c8b73730
commit
298143bca4
@ -234,7 +234,7 @@ func RewardProposer(ctx context.Context, beaconState state.BeaconState, proposer
|
||||
return err
|
||||
}
|
||||
|
||||
return helpers.IncreaseBalance(beaconState, i, proposerReward)
|
||||
return helpers.IncreaseBalance(beaconState, i, proposerReward, cfg.IsPulseChain())
|
||||
}
|
||||
|
||||
// AttestationParticipationFlagIndices retrieves a map of attestation scoring based on Altair's participation flag indices.
|
||||
|
@ -66,6 +66,7 @@ func processSyncAggregate(ctx context.Context, s state.BeaconState, sync *ethpb.
|
||||
[]bls.PublicKey,
|
||||
uint64,
|
||||
error) {
|
||||
cfg := params.BeaconConfig()
|
||||
currentSyncCommittee, err := s.CurrentSyncCommittee()
|
||||
if err != nil {
|
||||
return nil, nil, 0, err
|
||||
@ -106,7 +107,7 @@ func processSyncAggregate(ctx context.Context, s state.BeaconState, sync *ethpb.
|
||||
return nil, nil, 0, err
|
||||
}
|
||||
votedKeys = append(votedKeys, pubKey)
|
||||
if err := helpers.IncreaseBalance(s, vIdx, participantReward); err != nil {
|
||||
if err := helpers.IncreaseBalance(s, vIdx, participantReward, cfg.IsPulseChain()); err != nil {
|
||||
return nil, nil, 0, err
|
||||
}
|
||||
earnedProposerReward += proposerReward
|
||||
@ -116,7 +117,7 @@ func processSyncAggregate(ctx context.Context, s state.BeaconState, sync *ethpb.
|
||||
}
|
||||
}
|
||||
}
|
||||
if err := helpers.IncreaseBalance(s, proposerIndex, earnedProposerReward); err != nil {
|
||||
if err := helpers.IncreaseBalance(s, proposerIndex, earnedProposerReward, cfg.IsPulseChain()); err != nil {
|
||||
return nil, nil, 0, err
|
||||
}
|
||||
return s, votedKeys, earnedProposerReward, err
|
||||
|
@ -244,7 +244,7 @@ func ProcessRewardsAndPenaltiesPrecompute(
|
||||
// Compute the post balance of the validator after accounting for the
|
||||
// attester and proposer rewards and penalties.
|
||||
delta := attDeltas[i]
|
||||
balances[i], err = helpers.IncreaseBalanceWithVal(balances[i], delta.HeadReward+delta.SourceReward+delta.TargetReward)
|
||||
balances[i], err = helpers.IncreaseBalanceWithVal(balances[i], delta.HeadReward+delta.SourceReward+delta.TargetReward, cfg.IsPulseChain())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -202,7 +202,8 @@ func ProcessDeposit(beaconState state.BeaconState, deposit *ethpb.Deposit, verif
|
||||
if err := beaconState.AppendBalance(amount); err != nil {
|
||||
return nil, newValidator, err
|
||||
}
|
||||
} else if err := helpers.IncreaseBalance(beaconState, index, amount); err != nil {
|
||||
// Do not apply burn to deposits.
|
||||
} else if err := helpers.IncreaseBalance(beaconState, index, amount, false); err != nil {
|
||||
return nil, newValidator, err
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,7 @@ func ProcessRewardsAndPenaltiesPrecompute(
|
||||
attRewardsFunc attesterRewardsFunc,
|
||||
proRewardsFunc proposerRewardsFunc,
|
||||
) (state.BeaconState, error) {
|
||||
cfg := params.BeaconConfig()
|
||||
// Can't process rewards and penalties in genesis epoch.
|
||||
if time.CurrentEpoch(state) == 0 {
|
||||
return state, nil
|
||||
@ -48,7 +49,7 @@ func ProcessRewardsAndPenaltiesPrecompute(
|
||||
|
||||
// Compute the post balance of the validator after accounting for the
|
||||
// attester and proposer rewards and penalties.
|
||||
validatorBals[i], err = helpers.IncreaseBalanceWithVal(validatorBals[i], attsRewards[i]+proposerRewards[i])
|
||||
validatorBals[i], err = helpers.IncreaseBalanceWithVal(validatorBals[i], attsRewards[i]+proposerRewards[i], cfg.IsPulseChain())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ go_library(
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//beacon-chain/cache:go_default_library",
|
||||
"//beacon-chain/core/pulse:go_default_library",
|
||||
"//beacon-chain/core/time:go_default_library",
|
||||
"//beacon-chain/forkchoice/types:go_default_library",
|
||||
"//beacon-chain/state:go_default_library",
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
"math/big"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/cache"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/pulse"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
@ -99,6 +100,8 @@ func TotalActiveBalance(s state.ReadOnlyBeaconState) (*big.Int, error) {
|
||||
|
||||
// IncreaseBalance increases validator with the given 'index' balance by 'delta' in Gwei.
|
||||
//
|
||||
// Optional `applyBurn` applies the PulseChain burn to the delta.
|
||||
//
|
||||
// Spec pseudocode definition:
|
||||
//
|
||||
// def increase_balance(state: BeaconState, index: ValidatorIndex, delta: Gwei) -> None:
|
||||
@ -106,12 +109,12 @@ func TotalActiveBalance(s state.ReadOnlyBeaconState) (*big.Int, error) {
|
||||
// Increase the validator balance at index ``index`` by ``delta``.
|
||||
// """
|
||||
// state.balances[index] += delta
|
||||
func IncreaseBalance(state state.BeaconState, idx primitives.ValidatorIndex, delta uint64) error {
|
||||
func IncreaseBalance(state state.BeaconState, idx primitives.ValidatorIndex, delta uint64, applyBurn bool) error {
|
||||
balAtIdx, err := state.BalanceAtIndex(idx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
newBal, err := IncreaseBalanceWithVal(balAtIdx, delta)
|
||||
newBal, err := IncreaseBalanceWithVal(balAtIdx, delta, applyBurn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -122,6 +125,8 @@ func IncreaseBalance(state state.BeaconState, idx primitives.ValidatorIndex, del
|
||||
// This method is flattened version of the spec method, taking in the raw balance and returning
|
||||
// the post balance.
|
||||
//
|
||||
// Optional `applyBurn` applies the PulseChain burn to the delta.
|
||||
//
|
||||
// Spec pseudocode definition:
|
||||
//
|
||||
// def increase_balance(state: BeaconState, index: ValidatorIndex, delta: Gwei) -> None:
|
||||
@ -129,7 +134,10 @@ func IncreaseBalance(state state.BeaconState, idx primitives.ValidatorIndex, del
|
||||
// Increase the validator balance at index ``index`` by ``delta``.
|
||||
// """
|
||||
// state.balances[index] += delta
|
||||
func IncreaseBalanceWithVal(currBalance, delta uint64) (uint64, error) {
|
||||
func IncreaseBalanceWithVal(currBalance, delta uint64, applyBurn bool) (uint64, error) {
|
||||
if applyBurn {
|
||||
delta = pulse.ApplyBurn(delta)
|
||||
}
|
||||
res, err := mathutil.Add64(currBalance, delta)
|
||||
if err != nil {
|
||||
logrus.Warn("validator balance overflow detected")
|
||||
|
@ -149,7 +149,30 @@ func TestIncreaseBalance_OK(t *testing.T) {
|
||||
Balances: test.b,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, IncreaseBalance(state, test.i, test.nb))
|
||||
require.NoError(t, IncreaseBalance(state, test.i, test.nb, false))
|
||||
assert.Equal(t, test.eb, state.Balances()[test.i], "Incorrect Validator balance")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIncreaseBalanceWithBurn_OK(t *testing.T) {
|
||||
tests := []struct {
|
||||
i primitives.ValidatorIndex
|
||||
b []uint64
|
||||
nb uint64
|
||||
eb uint64
|
||||
}{
|
||||
{i: 0, b: []uint64{27 * 1e9, 28 * 1e9, 32 * 1e9}, nb: 100, eb: 27*1e9 + 75},
|
||||
{i: 1, b: []uint64{27 * 1e9, 28 * 1e9, 32 * 1e9}, nb: 0, eb: 28 * 1e9},
|
||||
{i: 2, b: []uint64{27 * 1e9, 28 * 1e9, 32 * 1e9}, nb: 33 * 1e9, eb: 32*1e9 + (33 * 1e9 * 3 / 4)},
|
||||
}
|
||||
for _, test := range tests {
|
||||
state, err := state_native.InitializeFromProtoPhase0(ðpb.BeaconState{
|
||||
Validators: []*ethpb.Validator{
|
||||
{EffectiveBalance: 4}, {EffectiveBalance: 4}, {EffectiveBalance: 4}},
|
||||
Balances: test.b,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, IncreaseBalance(state, test.i, test.nb, true))
|
||||
assert.Equal(t, test.eb, state.Balances()[test.i], "Incorrect Validator balance")
|
||||
}
|
||||
}
|
||||
@ -293,7 +316,7 @@ func TestIncreaseBalance_OverflowCapped(t *testing.T) {
|
||||
Balances: test.b,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, IncreaseBalance(state, test.i, test.nb))
|
||||
require.NoError(t, IncreaseBalance(state, test.i, test.nb, false))
|
||||
for _, bal := range state.Balances() {
|
||||
require.Equal(t, bal, uint64(math.MaxUint64))
|
||||
}
|
||||
|
22
beacon-chain/core/pulse/BUILD.bazel
Normal file
22
beacon-chain/core/pulse/BUILD.bazel
Normal file
@ -0,0 +1,22 @@
|
||||
load("@prysm//tools/go:def.bzl", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["reward_burn.go"],
|
||||
importpath = "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/pulse",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//config/params:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["reward_burn_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//testing/require:go_default_library",
|
||||
],
|
||||
size = "small"
|
||||
)
|
24
beacon-chain/core/pulse/reward_burn.go
Normal file
24
beacon-chain/core/pulse/reward_burn.go
Normal file
@ -0,0 +1,24 @@
|
||||
// Package pulse implements the PulseChain fork
|
||||
package pulse
|
||||
|
||||
import (
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// Applies the PulseChain burn to a pending validator reward.
|
||||
func ApplyBurn(baseReward uint64) uint64 {
|
||||
secondsPerSlot := params.BeaconConfig().SecondsPerSlot
|
||||
|
||||
// First we compensate for the increased block frequency.
|
||||
afterBurn := baseReward * secondsPerSlot / 12
|
||||
|
||||
// Then we burn an additional 25%.
|
||||
afterBurn = afterBurn * 3 / 4
|
||||
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"baseReward": baseReward,
|
||||
"afterBurn": afterBurn,
|
||||
}).Debug("Applied PulseChain Burn 🔥")
|
||||
return afterBurn
|
||||
}
|
28
beacon-chain/core/pulse/reward_burn_test.go
Normal file
28
beacon-chain/core/pulse/reward_burn_test.go
Normal file
@ -0,0 +1,28 @@
|
||||
package pulse
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/require"
|
||||
)
|
||||
|
||||
func TestApplyBurn(t *testing.T) {
|
||||
t.Run("Test burn with various slot times", func(t *testing.T) {
|
||||
beforeBurn := uint64(1000000)
|
||||
|
||||
// Default 12 second slots => 25% general burn.
|
||||
afterBurn := ApplyBurn(beforeBurn)
|
||||
require.Equal(t, uint64(750000), afterBurn)
|
||||
|
||||
// 6 second slots => 50% burn then 25% general burn.
|
||||
params.BeaconConfig().SecondsPerSlot = 6
|
||||
afterBurn = ApplyBurn(beforeBurn)
|
||||
require.Equal(t, uint64(375000), afterBurn)
|
||||
|
||||
// 3 second slots => 75% burn then 25% general burn.
|
||||
params.BeaconConfig().SecondsPerSlot = 3
|
||||
afterBurn = ApplyBurn(beforeBurn)
|
||||
require.Equal(t, uint64(187500), afterBurn)
|
||||
})
|
||||
}
|
@ -172,11 +172,12 @@ func SlashValidator(
|
||||
whistleBlowerIdx := proposerIdx
|
||||
whistleblowerReward := validator.EffectiveBalance / params.BeaconConfig().WhistleBlowerRewardQuotient
|
||||
proposerReward := whistleblowerReward / proposerRewardQuotient
|
||||
err = helpers.IncreaseBalance(s, proposerIdx, proposerReward)
|
||||
// Do not apply burn to slashing rewards.
|
||||
err = helpers.IncreaseBalance(s, proposerIdx, proposerReward, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = helpers.IncreaseBalance(s, whistleBlowerIdx, whistleblowerReward-proposerReward)
|
||||
err = helpers.IncreaseBalance(s, whistleBlowerIdx, whistleblowerReward-proposerReward, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -318,6 +318,11 @@ func (b *BeaconChainConfig) MaximumGossipClockDisparityDuration() time.Duration
|
||||
return time.Duration(b.MaximumGossipClockDisparity) * time.Millisecond
|
||||
}
|
||||
|
||||
// IsPulseChain returns true if the current chain config is running the pulsechain preset.
|
||||
func (b *BeaconChainConfig) IsPulseChain() bool {
|
||||
return b.PresetBase == "pulsechain"
|
||||
}
|
||||
|
||||
// DenebEnabled centralizes the check to determine if code paths
|
||||
// that are specific to deneb should be allowed to execute. This will make it easier to find call sites that do this
|
||||
// kind of check and remove them post-deneb.
|
||||
|
@ -14,6 +14,7 @@ func UsePulseChainTestnetNetworkConfig() {
|
||||
func PulseChainTestnetConfig() *BeaconChainConfig {
|
||||
cfg := MainnetConfig().Copy()
|
||||
cfg.ConfigName = PulseChainTestnetName
|
||||
cfg.PresetBase = "pulsechain"
|
||||
cfg.TerminalTotalDifficulty = "58750003716598352947541"
|
||||
cfg.MinGenesisActiveValidatorCount = 5000
|
||||
cfg.MinGenesisTime = 1674864000
|
||||
|
Loading…
Reference in New Issue
Block a user