mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2025-01-10 11:41:21 +00:00
57a323f083
* Compiling main beacon-chain binary * Add feature flag * passing protoarray tests * passing nodetree tests * passing blockchain package tests * passing rpc tests * go fmt * re-export forkchoice store from blockchain package * remove duplicated import * remove unused var * add nodetree rpc method * remove slot from IsOptimisticForRoot * release lock in IsOptimistic * change package name * Revert "change package name" This reverts commit 679112f9ef795922c631e7823dbdfb3746838f3c. * rename package * Update doc * Fix span names * Terence + Raul review * remove go:build flags * add errors dep * spec tests * fix call to IsOptimisticForRoot * fix test * Fix conflict * change name of function * remove ctx from store.head Co-authored-by: terence tsao <terence@prysmaticlabs.com>
93 lines
2.7 KiB
Go
93 lines
2.7 KiB
Go
package protoarray
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/prysmaticlabs/prysm/config/params"
|
|
"go.opencensus.io/trace"
|
|
)
|
|
|
|
// This computes validator balance delta from validator votes.
|
|
// It returns a list of deltas that represents the difference between old balances and new balances.
|
|
func computeDeltas(
|
|
ctx context.Context,
|
|
blockIndices map[[32]byte]uint64,
|
|
votes []Vote,
|
|
oldBalances, newBalances []uint64,
|
|
) ([]int, []Vote, error) {
|
|
_, span := trace.StartSpan(ctx, "doublyLinkedForkchoice.computeDeltas")
|
|
defer span.End()
|
|
|
|
deltas := make([]int, len(blockIndices))
|
|
|
|
for validatorIndex, vote := range votes {
|
|
oldBalance := uint64(0)
|
|
newBalance := uint64(0)
|
|
|
|
// Skip if validator has never voted for current root and next root (i.e. if the
|
|
// votes are zero hash aka genesis block), there's nothing to compute.
|
|
if vote.currentRoot == params.BeaconConfig().ZeroHash && vote.nextRoot == params.BeaconConfig().ZeroHash {
|
|
continue
|
|
}
|
|
|
|
// If the validator index did not exist in `oldBalance` or `newBalance` list above, the balance is just 0.
|
|
if validatorIndex < len(oldBalances) {
|
|
oldBalance = oldBalances[validatorIndex]
|
|
}
|
|
if validatorIndex < len(newBalances) {
|
|
newBalance = newBalances[validatorIndex]
|
|
}
|
|
|
|
// Perform delta only if the validator's balance or vote has changed.
|
|
if vote.currentRoot != vote.nextRoot || oldBalance != newBalance {
|
|
// Ignore the vote if it's not known in `blockIndices`,
|
|
// that means we have not seen the block before.
|
|
nextDeltaIndex, ok := blockIndices[vote.nextRoot]
|
|
if ok {
|
|
// Protection against out of bound, the `nextDeltaIndex` which defines
|
|
// the block location in the dag can not exceed the total `delta` length.
|
|
if int(nextDeltaIndex) >= len(deltas) {
|
|
return nil, nil, errInvalidNodeDelta
|
|
}
|
|
deltas[nextDeltaIndex] += int(newBalance)
|
|
}
|
|
|
|
currentDeltaIndex, ok := blockIndices[vote.currentRoot]
|
|
if ok {
|
|
// Protection against out of bound (same as above)
|
|
if int(currentDeltaIndex) >= len(deltas) {
|
|
return nil, nil, errInvalidNodeDelta
|
|
}
|
|
deltas[currentDeltaIndex] -= int(oldBalance)
|
|
}
|
|
}
|
|
|
|
// Rotate the validator vote.
|
|
vote.currentRoot = vote.nextRoot
|
|
votes[validatorIndex] = vote
|
|
}
|
|
|
|
return deltas, votes, nil
|
|
}
|
|
|
|
// This return a copy of the proto array node object.
|
|
func copyNode(node *Node) *Node {
|
|
if node == nil {
|
|
return &Node{}
|
|
}
|
|
|
|
copiedRoot := [32]byte{}
|
|
copy(copiedRoot[:], node.root[:])
|
|
|
|
return &Node{
|
|
slot: node.slot,
|
|
root: copiedRoot,
|
|
parent: node.parent,
|
|
justifiedEpoch: node.justifiedEpoch,
|
|
finalizedEpoch: node.finalizedEpoch,
|
|
weight: node.weight,
|
|
bestChild: node.bestChild,
|
|
bestDescendant: node.bestDescendant,
|
|
}
|
|
}
|