Skip to content

Commit

Permalink
Add Reference Copying (#5245)
Browse files Browse the repository at this point in the history
* add state changes
* add new changes
* add flag
* lint
* add flag
* change to correct bool
* fixing and consolidating trie
* lint
* Apply suggestions from code review
* Merge refs/heads/master into addBetterCopying
* Merge branch 'master' into addBetterCopying
* refCopy -> stateRefCopy
* Merge refs/heads/master into addBetterCopying
* tests whether unexpected mutation of validators within state is avoided
* Merge branch 'addBetterCopying' of github.com:prysmaticlabs/prysm into addBetterCopying
* remove unnecessary fields
* gazelle
* updates test
* avoid unexpected mutation in block roots on refcopy
* avoid unexpected mutation in state roots on refcopy
* Merge refs/heads/master into addBetterCopying
* Merge branch 'master' into addBetterCopying
* fix test
* randao tests
* simplify tests
* Merge refs/heads/master into addBetterCopying
* Merge refs/heads/master into addBetterCopying
* Merge refs/heads/master into addBetterCopying
* Merge refs/heads/master into addBetterCopying
* test cur/prev attestations mutation
* Merge branch 'addBetterCopying' of github.com:prysmaticlabs/prysm into addBetterCopying
* gazelle
* Merge refs/heads/master into addBetterCopying
* Merge refs/heads/master into addBetterCopying
* Merge refs/heads/master into addBetterCopying
* Merge refs/heads/master into addBetterCopying
* Merge refs/heads/master into addBetterCopying
* Merge refs/heads/master into addBetterCopying
* Merge refs/heads/master into addBetterCopying
* fixes tests
* minor naming update
* Merge refs/heads/master into addBetterCopying
* Merge refs/heads/master into addBetterCopying
* Merge refs/heads/master into addBetterCopying
* Merge refs/heads/master into addBetterCopying
* Merge refs/heads/master into addBetterCopying
* Merge refs/heads/master into addBetterCopying
* Merge refs/heads/master into addBetterCopying
* Merge refs/heads/master into addBetterCopying
* Merge refs/heads/master into addBetterCopying
* Merge refs/heads/master into addBetterCopying
* Merge refs/heads/master into addBetterCopying
* Merge refs/heads/master into addBetterCopying
* Merge refs/heads/master into addBetterCopying
* Merge refs/heads/master into addBetterCopying
* Merge refs/heads/master into addBetterCopying
* Merge refs/heads/master into addBetterCopying
* Merge refs/heads/master into addBetterCopying
* Merge refs/heads/master into addBetterCopying
* Merge refs/heads/master into addBetterCopying
* Merge refs/heads/master into addBetterCopying
* Merge refs/heads/master into addBetterCopying
* Merge refs/heads/master into addBetterCopying
* Merge refs/heads/master into addBetterCopying
* Merge refs/heads/master into addBetterCopying
* Merge refs/heads/master into addBetterCopying
* Merge refs/heads/master into addBetterCopying
* Merge refs/heads/master into addBetterCopying
  • Loading branch information
nisdas committed Apr 19, 2020
1 parent dee3f02 commit 626b3e0
Show file tree
Hide file tree
Showing 12 changed files with 660 additions and 78 deletions.
40 changes: 31 additions & 9 deletions beacon-chain/core/epoch/epoch_processing.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,21 +168,29 @@ func ProcessSlashings(state *stateTrie.BeaconState) (*stateTrie.BeaconState, err
totalSlashing += slashing
}

checker := func(idx int, val *ethpb.Validator) (bool, error) {
correctEpoch := (currentEpoch + exitLength/2) == val.WithdrawableEpoch
if val.Slashed && correctEpoch {
return true, nil
}
return false, nil
}

// a callback is used here to apply the following actions to all validators
// below equally.
err = state.ApplyToEveryValidator(func(idx int, val *ethpb.Validator) (bool, error) {
err = state.ApplyToEveryValidator(checker, func(idx int, val *ethpb.Validator) error {
correctEpoch := (currentEpoch + exitLength/2) == val.WithdrawableEpoch
if val.Slashed && correctEpoch {
minSlashing := mathutil.Min(totalSlashing*3, totalBalance)
increment := params.BeaconConfig().EffectiveBalanceIncrement
penaltyNumerator := val.EffectiveBalance / increment * minSlashing
penalty := penaltyNumerator / totalBalance * increment
if err := helpers.DecreaseBalance(state, uint64(idx), penalty); err != nil {
return false, err
return err
}
return true, nil
return nil
}
return false, nil
return nil
})
return state, err
}
Expand Down Expand Up @@ -238,8 +246,7 @@ func ProcessFinalUpdates(state *stateTrie.BeaconState) (*stateTrie.BeaconState,
}

bals := state.Balances()
// Update effective balances with hysteresis.
validatorFunc := func(idx int, val *ethpb.Validator) (bool, error) {
checker := func(idx int, val *ethpb.Validator) (bool, error) {
if val == nil {
return false, fmt.Errorf("validator %d is nil in state", idx)
}
Expand All @@ -254,14 +261,29 @@ func ProcessFinalUpdates(state *stateTrie.BeaconState) (*stateTrie.BeaconState,
if balance+downwardThreshold < val.EffectiveBalance || val.EffectiveBalance+upwardThreshold < balance {
val.EffectiveBalance = params.BeaconConfig().MaxEffectiveBalance
if val.EffectiveBalance > balance-balance%params.BeaconConfig().EffectiveBalanceIncrement {
val.EffectiveBalance = balance - balance%params.BeaconConfig().EffectiveBalanceIncrement
return true, nil
}
return true, nil
}
return false, nil
}
// Update effective balances with hysteresis.
updateEffectiveBalances := func(idx int, val *ethpb.Validator) error {
balance := bals[idx]
hysteresisInc := params.BeaconConfig().EffectiveBalanceIncrement / params.BeaconConfig().HysteresisQuotient
downwardThreshold := hysteresisInc * params.BeaconConfig().HysteresisDownwardMultiplier
upwardThreshold := hysteresisInc * params.BeaconConfig().HysteresisUpwardMultiplier

if balance+downwardThreshold < val.EffectiveBalance || val.EffectiveBalance+upwardThreshold < balance {
val.EffectiveBalance = params.BeaconConfig().MaxEffectiveBalance
if val.EffectiveBalance > balance-balance%params.BeaconConfig().EffectiveBalanceIncrement {
val.EffectiveBalance = balance - balance%params.BeaconConfig().EffectiveBalanceIncrement
}
return nil
}
return nil
}

if err := state.ApplyToEveryValidator(validatorFunc); err != nil {
if err := state.ApplyToEveryValidator(checker, updateEffectiveBalances); err != nil {
return nil, err
}

Expand Down
18 changes: 13 additions & 5 deletions beacon-chain/core/epoch/precompute/slashing.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,28 @@ func ProcessSlashingsPrecompute(state *stateTrie.BeaconState, p *Balance) error
totalSlashing += slashing
}

validatorFunc := func(idx int, val *ethpb.Validator) (bool, error) {
checker := func(idx int, val *ethpb.Validator) (bool, error) {
correctEpoch := (currentEpoch + exitLength/2) == val.WithdrawableEpoch
if val.Slashed && correctEpoch {
return true, nil
}
return false, nil
}

updateEffectiveBalances := func(idx int, val *ethpb.Validator) error {
correctEpoch := (currentEpoch + exitLength/2) == val.WithdrawableEpoch
if val.Slashed && correctEpoch {
minSlashing := mathutil.Min(totalSlashing*3, p.CurrentEpoch)
increment := params.BeaconConfig().EffectiveBalanceIncrement
penaltyNumerator := val.EffectiveBalance / increment * minSlashing
penalty := penaltyNumerator / p.CurrentEpoch * increment
if err := helpers.DecreaseBalance(state, uint64(idx), penalty); err != nil {
return false, err
return err
}
return true, nil
return nil
}
return false, nil
return nil
}

return state.ApplyToEveryValidator(validatorFunc)
return state.ApplyToEveryValidator(checker, updateEffectiveBalances)
}
2 changes: 2 additions & 0 deletions beacon-chain/state/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,13 @@ go_test(
"//beacon-chain/state/stateutil:go_default_library",
"//proto/beacon/p2p/v1:go_default_library",
"//shared/bytesutil:go_default_library",
"//shared/featureconfig:go_default_library",
"//shared/interop:go_default_library",
"//shared/params:go_default_library",
"//shared/testutil:go_default_library",
"@com_github_gogo_protobuf//proto:go_default_library",
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
"@com_github_prysmaticlabs_go_ssz//:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
],
Expand Down
18 changes: 18 additions & 0 deletions beacon-chain/state/cloners.go
Original file line number Diff line number Diff line change
Expand Up @@ -266,3 +266,21 @@ func CopySignedVoluntaryExit(exit *ethpb.SignedVoluntaryExit) *ethpb.SignedVolun
Signature: bytesutil.SafeCopyBytes(exit.Signature),
}
}

// CopyValidator copies the provided validator.
func CopyValidator(val *ethpb.Validator) *ethpb.Validator {
pubKey := make([]byte, len(val.PublicKey))
copy(pubKey, val.PublicKey)
withdrawalCreds := make([]byte, len(val.WithdrawalCredentials))
copy(withdrawalCreds, val.WithdrawalCredentials)
return &ethpb.Validator{
PublicKey: pubKey[:],
WithdrawalCredentials: withdrawalCreds,
EffectiveBalance: val.EffectiveBalance,
Slashed: val.Slashed,
ActivationEligibilityEpoch: val.ActivationEligibilityEpoch,
ActivationEpoch: val.ActivationEpoch,
ExitEpoch: val.ExitEpoch,
WithdrawableEpoch: val.WithdrawableEpoch,
}
}
8 changes: 4 additions & 4 deletions beacon-chain/state/field_trie.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,10 +113,10 @@ func (f *FieldTrie) CopyTrie() *FieldTrie {
switch f.field {
case randaoMixes:
dstFieldTrie = memorypool.GetRandaoMixesTrie(len(f.fieldLayers))
case blockRoots:
dstFieldTrie = memorypool.GetBlockRootsTrie(len(f.fieldLayers))
case stateRoots:
dstFieldTrie = memorypool.GetStateRootsTrie(len(f.fieldLayers))
case blockRoots, stateRoots:
dstFieldTrie = memorypool.GetRootsTrie(len(f.fieldLayers))
case validators:
dstFieldTrie = memorypool.GetValidatorsTrie(len(f.fieldLayers))
default:
dstFieldTrie = make([][]*[32]byte, len(f.fieldLayers))
}
Expand Down
20 changes: 6 additions & 14 deletions beacon-chain/state/getters.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ func (v *ReadOnlyValidator) Slashed() bool {
return v.validator.Slashed
}

// CopyValidator returns the copy of the read only validator.
func (v *ReadOnlyValidator) CopyValidator() *ethpb.Validator {
return CopyValidator(v.validator)
}

// InnerStateUnsafe returns the pointer value of the underlying
// beacon state proto object, bypassing immutability. Use with care.
func (b *BeaconState) InnerStateUnsafe() *pbp2p.BeaconState {
Expand Down Expand Up @@ -366,20 +371,7 @@ func (b *BeaconState) Validators() []*ethpb.Validator {
if val == nil {
continue
}
pubKey := make([]byte, len(val.PublicKey))
copy(pubKey, val.PublicKey)
withdrawalCreds := make([]byte, len(val.WithdrawalCredentials))
copy(withdrawalCreds, val.WithdrawalCredentials)
res[i] = &ethpb.Validator{
PublicKey: pubKey[:],
WithdrawalCredentials: withdrawalCreds,
EffectiveBalance: val.EffectiveBalance,
Slashed: val.Slashed,
ActivationEligibilityEpoch: val.ActivationEligibilityEpoch,
ActivationEpoch: val.ActivationEpoch,
ExitEpoch: val.ExitEpoch,
WithdrawableEpoch: val.WithdrawableEpoch,
}
res[i] = CopyValidator(val)
}
return res
}
Expand Down

0 comments on commit 626b3e0

Please sign in to comment.