mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2024-12-23 11:57:18 +00:00
More efficient way of computing skip slot cache key (#11441)
* More efficient way of computing skip slot cache key * Gazelle * Add defensive check * Fix test setup * Disable skip slot cache * Fix rpc tests for dependent root
This commit is contained in:
parent
1696208318
commit
0f0d480dbc
@ -6,6 +6,7 @@ import (
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v3/beacon-chain/cache"
|
||||
"github.com/prysmaticlabs/prysm/v3/beacon-chain/core/signing"
|
||||
"github.com/prysmaticlabs/prysm/v3/beacon-chain/core/transition"
|
||||
dbtest "github.com/prysmaticlabs/prysm/v3/beacon-chain/db/testing"
|
||||
doublylinkedtree "github.com/prysmaticlabs/prysm/v3/beacon-chain/forkchoice/doubly-linked-tree"
|
||||
"github.com/prysmaticlabs/prysm/v3/beacon-chain/state/stategen"
|
||||
@ -53,6 +54,7 @@ func TestService_HeadDomainFetcher_Errors(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestService_HeadSyncCommitteeIndices(t *testing.T) {
|
||||
transition.SkipSlotCache.Disable()
|
||||
s, _ := util.DeterministicGenesisStateAltair(t, params.BeaconConfig().TargetCommitteeSize)
|
||||
c := &Service{}
|
||||
c.head = &head{state: s}
|
||||
|
@ -281,7 +281,10 @@ func (s *ChainService) HeadBlock(context.Context) (interfaces.SignedBeaconBlock,
|
||||
|
||||
// HeadState mocks HeadState method in chain service.
|
||||
func (s *ChainService) HeadState(context.Context) (state.BeaconState, error) {
|
||||
return s.State, nil
|
||||
if s.State == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return s.State.Copy(), nil
|
||||
}
|
||||
|
||||
// CurrentFork mocks HeadState method in chain service.
|
||||
|
@ -40,7 +40,6 @@ go_library(
|
||||
"//consensus-types/interfaces:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//crypto/bls:go_default_library",
|
||||
"//crypto/hash:go_default_library",
|
||||
"//encoding/bytesutil:go_default_library",
|
||||
"//math:go_default_library",
|
||||
"//monitoring/tracing:go_default_library",
|
||||
|
@ -6,7 +6,6 @@ import (
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v3/beacon-chain/cache"
|
||||
"github.com/prysmaticlabs/prysm/v3/beacon-chain/state"
|
||||
"github.com/prysmaticlabs/prysm/v3/crypto/hash"
|
||||
"github.com/prysmaticlabs/prysm/v3/encoding/bytesutil"
|
||||
)
|
||||
|
||||
@ -16,17 +15,23 @@ import (
|
||||
// reasonable amount of time.
|
||||
var SkipSlotCache = cache.NewSkipSlotCache()
|
||||
|
||||
// The key for skip slot cache is mixed between state root and state slot.
|
||||
// SkipSlotCacheKey is the key for skip slot cache is mixed between state root and state slot.
|
||||
// state root is in the mix to defend against different forks with same skip slots
|
||||
// to hit the same cache. We don't want beacon states mixed up between different chains.
|
||||
func cacheKey(_ context.Context, state state.ReadOnlyBeaconState) ([32]byte, error) {
|
||||
// [0:24] represents the state root
|
||||
// [24:32] represents the state slot
|
||||
func SkipSlotCacheKey(_ context.Context, state state.ReadOnlyBeaconState) ([32]byte, error) {
|
||||
bh := state.LatestBlockHeader()
|
||||
if bh == nil {
|
||||
return [32]byte{}, errors.New("block head in state can't be nil")
|
||||
}
|
||||
r, err := bh.HashTreeRoot()
|
||||
if err != nil {
|
||||
return [32]byte{}, err
|
||||
sr := bh.StateRoot
|
||||
if len(sr) != 32 {
|
||||
return [32]byte{}, errors.New("invalid state root in latest block header")
|
||||
}
|
||||
return hash.Hash(append(bytesutil.Bytes32(uint64(state.Slot())), r[:]...)), nil
|
||||
|
||||
var b [8]byte
|
||||
copy(b[:], bytesutil.SlotToBytesBigEndian(state.Slot()))
|
||||
sr = append(sr[:24], b[:]...)
|
||||
return bytesutil.ToBytes32(sr), nil
|
||||
}
|
||||
|
@ -10,6 +10,8 @@ import (
|
||||
state_native "github.com/prysmaticlabs/prysm/v3/beacon-chain/state/state-native"
|
||||
"github.com/prysmaticlabs/prysm/v3/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v3/consensus-types/blocks"
|
||||
"github.com/prysmaticlabs/prysm/v3/encoding/bytesutil"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v3/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v3/runtime/version"
|
||||
"github.com/prysmaticlabs/prysm/v3/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v3/testing/require"
|
||||
@ -80,6 +82,8 @@ func TestSkipSlotCache_ConcurrentMixup(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
s1, err = transition.ExecuteStateTransition(context.Background(), originalState.Copy(), wsb)
|
||||
require.NoError(t, err, "Could not run state transition")
|
||||
s1, err = transition.ProcessSlot(context.Background(), s1)
|
||||
require.NoError(t, err, "Could not process slot")
|
||||
}
|
||||
|
||||
{
|
||||
@ -93,6 +97,8 @@ func TestSkipSlotCache_ConcurrentMixup(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
s0, err = transition.ExecuteStateTransition(context.Background(), originalState.Copy(), wsb)
|
||||
require.NoError(t, err, "Could not run state transition")
|
||||
s0, err = transition.ProcessSlot(context.Background(), s0)
|
||||
require.NoError(t, err, "Could not process slot")
|
||||
}
|
||||
|
||||
r1, err := s1.HashTreeRoot(context.Background())
|
||||
@ -167,3 +173,28 @@ func TestSkipSlotCache_ConcurrentMixup(t *testing.T) {
|
||||
// Wait for all transitions to finish
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func TestSkipSlotCacheKey(t *testing.T) {
|
||||
st, _ := util.DeterministicGenesisState(t, 100)
|
||||
require.NoError(t, st.SetSlot(1))
|
||||
k, err := transition.SkipSlotCacheKey(context.Background(), st)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, [32]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, k)
|
||||
|
||||
require.NoError(t, st.SetLatestBlockHeader(ðpb.BeaconBlockHeader{
|
||||
StateRoot: bytesutil.PadTo([]byte{1, 2, 3, 4}, 32),
|
||||
}))
|
||||
k, err = transition.SkipSlotCacheKey(context.Background(), st)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, [32]byte{1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, k)
|
||||
}
|
||||
|
||||
func BenchmarkCacheKey(b *testing.B) {
|
||||
st, _ := util.DeterministicGenesisState(b, 100)
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, err := transition.SkipSlotCacheKey(context.Background(), st)
|
||||
require.NoError(b, err)
|
||||
}
|
||||
}
|
||||
|
@ -200,7 +200,7 @@ func ProcessSlots(ctx context.Context, state state.BeaconState, slot types.Slot)
|
||||
}
|
||||
|
||||
highestSlot := state.Slot()
|
||||
key, err := cacheKey(ctx, state)
|
||||
key, err := SkipSlotCacheKey(ctx, state)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -446,6 +446,7 @@ func TestSubmitAttesterSlashing_Ok(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestSubmitAttesterSlashing_AcrossFork(t *testing.T) {
|
||||
transition.SkipSlotCache.Disable()
|
||||
ctx := context.Background()
|
||||
|
||||
params.SetupTestConfigCleanup(t)
|
||||
|
@ -973,6 +973,7 @@ func attestationDependentRoot(s state.BeaconState, epoch types.Epoch) ([]byte, e
|
||||
}
|
||||
dependentRootSlot = prevEpochStartSlot.Sub(1)
|
||||
}
|
||||
|
||||
root, err := helpers.BlockRootAtSlot(s, dependentRootSlot)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get block root")
|
||||
|
@ -176,6 +176,9 @@ func TestGetAttesterDuties(t *testing.T) {
|
||||
}
|
||||
resp, err := vs.GetAttesterDuties(ctx, req)
|
||||
require.NoError(t, err)
|
||||
|
||||
bs, err = transition.ProcessSlotsIfPossible(ctx, bs, params.BeaconConfig().SlotsPerEpoch*2)
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, bs.BlockRoots()[31], resp.DependentRoot)
|
||||
require.Equal(t, 1, len(resp.Data))
|
||||
duty := resp.Data[0]
|
||||
@ -359,6 +362,9 @@ func TestGetProposerDuties(t *testing.T) {
|
||||
}
|
||||
resp, err := vs.GetProposerDuties(ctx, req)
|
||||
require.NoError(t, err)
|
||||
|
||||
bs, err = transition.ProcessSlotsIfPossible(ctx, bs, params.BeaconConfig().SlotsPerEpoch*2)
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, bs.BlockRoots()[31], resp.DependentRoot)
|
||||
assert.Equal(t, 32, len(resp.Data))
|
||||
// We expect a proposer duty for slot 74.
|
||||
|
@ -15,6 +15,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v3/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/v3/beacon-chain/core/signing"
|
||||
prysmtime "github.com/prysmaticlabs/prysm/v3/beacon-chain/core/time"
|
||||
"github.com/prysmaticlabs/prysm/v3/beacon-chain/core/transition"
|
||||
dbTest "github.com/prysmaticlabs/prysm/v3/beacon-chain/db/testing"
|
||||
mockExecution "github.com/prysmaticlabs/prysm/v3/beacon-chain/execution/testing"
|
||||
doublylinkedtree "github.com/prysmaticlabs/prysm/v3/beacon-chain/forkchoice/doubly-linked-tree"
|
||||
@ -528,6 +529,7 @@ func TestServer_getAndBuildHeaderBlock(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_GetBellatrixBeaconBlock_HappyCase(t *testing.T) {
|
||||
transition.SkipSlotCache.Disable()
|
||||
db := dbTest.SetupDB(t)
|
||||
ctx := context.Background()
|
||||
hook := logTest.NewGlobal()
|
||||
|
@ -19,6 +19,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v3/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/v3/beacon-chain/core/signing"
|
||||
coretime "github.com/prysmaticlabs/prysm/v3/beacon-chain/core/time"
|
||||
"github.com/prysmaticlabs/prysm/v3/beacon-chain/core/transition"
|
||||
dbutil "github.com/prysmaticlabs/prysm/v3/beacon-chain/db/testing"
|
||||
mockExecution "github.com/prysmaticlabs/prysm/v3/beacon-chain/execution/testing"
|
||||
doublylinkedtree "github.com/prysmaticlabs/prysm/v3/beacon-chain/forkchoice/doubly-linked-tree"
|
||||
@ -2089,6 +2090,7 @@ func TestProposer_GetBeaconBlock_PostForkEpoch(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestProposer_GetBeaconBlock_BellatrixEpoch(t *testing.T) {
|
||||
transition.SkipSlotCache.Disable()
|
||||
db := dbutil.SetupDB(t)
|
||||
ctx := context.Background()
|
||||
hook := logTest.NewGlobal()
|
||||
|
Loading…
Reference in New Issue
Block a user