Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bound Initial Sync Cache Size #4844

Merged
merged 83 commits into from Feb 18, 2020
Merged
Show file tree
Hide file tree
Changes from 74 commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
6a60325
bound initial sync
nisdas Feb 12, 2020
ba918e3
Merge branch 'master' into OOMFix
nisdas Feb 12, 2020
54a51c3
Merge branch 'OOMFix' of github.com:prysmaticlabs/prysm into OOMFix
rauljordan Feb 12, 2020
ef8b9a4
fix lint
rauljordan Feb 12, 2020
dc489e9
Revert "Better block attestation inclusion (#4838)"
rauljordan Feb 12, 2020
dc5176d
add memory pool
nisdas Feb 13, 2020
a8afaa3
more fixes
nisdas Feb 13, 2020
dfbe81a
Merge branch 'master' of https://github.com/prysmaticlabs/geth-shardi…
nisdas Feb 14, 2020
386668a
revert changes
nisdas Feb 14, 2020
bb103b0
add hack
nisdas Feb 14, 2020
66aefaa
revert hack
nisdas Feb 14, 2020
026415c
push halving
nisdas Feb 14, 2020
3b7258a
bring back hack
nisdas Feb 14, 2020
17d1d11
Merge branch 'master' of https://github.com/prysmaticlabs/geth-shardi…
nisdas Feb 14, 2020
771eca3
increase cache size
nisdas Feb 14, 2020
afa5074
more fixes
nisdas Feb 14, 2020
9775983
more changes
nisdas Feb 15, 2020
3ff5133
new fixes
nisdas Feb 16, 2020
ee7bc62
Merge branch 'master' of https://github.com/prysmaticlabs/geth-shardi…
nisdas Feb 16, 2020
d034213
add test
nisdas Feb 16, 2020
56f9d1c
add reverse test
nisdas Feb 16, 2020
478c495
more tests and clean up
nisdas Feb 16, 2020
6556570
add helper
nisdas Feb 16, 2020
7b2c0ff
more cleanup and tests
nisdas Feb 16, 2020
09c92c9
fix test
nisdas Feb 16, 2020
64c868c
remove code
nisdas Feb 16, 2020
c8bdcbe
set gc percent flag
nisdas Feb 16, 2020
21d7c87
lint
nisdas Feb 16, 2020
9cd5d0f
lint
nisdas Feb 16, 2020
0826591
Fix comment formatting
0xKiwi Feb 16, 2020
9500ab5
Fix some formatting
0xKiwi Feb 16, 2020
0887bc8
inverse if statement
nisdas Feb 16, 2020
7df80b7
remove debug log
nisdas Feb 16, 2020
ea91ad1
Apply suggestions from code review
nisdas Feb 16, 2020
0fac774
Update beacon-chain/state/getters.go
nisdas Feb 16, 2020
b18c68d
Update beacon-chain/db/kv/state.go
nisdas Feb 16, 2020
b368a8b
Merge branch 'master' into OOMFix
prestonvanloon Feb 16, 2020
700237d
Merge refs/heads/master into OOMFix
prylabs-bulldozer[bot] Feb 16, 2020
e67dd1b
Merge refs/heads/master into OOMFix
prylabs-bulldozer[bot] Feb 16, 2020
2f53667
Merge refs/heads/master into OOMFix
prylabs-bulldozer[bot] Feb 16, 2020
9eabd89
integrate state generator
nisdas Feb 17, 2020
a12826c
gaz
nisdas Feb 17, 2020
34b8969
fixes
nisdas Feb 17, 2020
2c55ee9
Merge branch 'master' of https://github.com/prysmaticlabs/geth-shardi…
nisdas Feb 17, 2020
f7b53aa
terence's review
nisdas Feb 17, 2020
6cd8218
reduce bound further
nisdas Feb 17, 2020
c05b809
fix test
nisdas Feb 17, 2020
7f495c2
separate into new files
nisdas Feb 17, 2020
2dad4cd
gaz
nisdas Feb 17, 2020
3704e7b
mod build file
nisdas Feb 17, 2020
5b51607
add test
nisdas Feb 17, 2020
2e5c6b1
revert changes
nisdas Feb 17, 2020
63bd182
fix test
nisdas Feb 17, 2020
c11b029
Update beacon-chain/core/helpers/slot_epoch.go
nisdas Feb 17, 2020
8986e9f
handle edge case
nisdas Feb 17, 2020
86ca9b3
Merge branch 'OOMFix' of https://github.com/prysmaticlabs/geth-shardi…
nisdas Feb 17, 2020
96b56eb
add back test
nisdas Feb 17, 2020
91c18da
fix test again
nisdas Feb 17, 2020
d904f3b
handle edge case
nisdas Feb 17, 2020
9bf5e60
Update beacon-chain/blockchain/init_sync_process_block.go
rauljordan Feb 17, 2020
073a164
Update beacon-chain/blockchain/init_sync_process_block.go
rauljordan Feb 17, 2020
4d2c684
Merge refs/heads/master into OOMFix
prylabs-bulldozer[bot] Feb 17, 2020
402cbfa
Merge refs/heads/master into OOMFix
prylabs-bulldozer[bot] Feb 17, 2020
6ef46d6
Merge refs/heads/master into OOMFix
prylabs-bulldozer[bot] Feb 17, 2020
19b13d5
Merge refs/heads/master into OOMFix
prylabs-bulldozer[bot] Feb 17, 2020
f2407d4
Merge refs/heads/master into OOMFix
prylabs-bulldozer[bot] Feb 17, 2020
564f3b1
Update beacon-chain/stategen/service_test.go
nisdas Feb 18, 2020
17ded5e
Update beacon-chain/blockchain/init_sync_process_block.go
nisdas Feb 18, 2020
330138f
Update beacon-chain/stategen/service.go
nisdas Feb 18, 2020
21f56b1
Update beacon-chain/stategen/service.go
nisdas Feb 18, 2020
2f2aa2a
raul's review
nisdas Feb 18, 2020
499f672
Merge branch 'OOMFix' of https://github.com/prysmaticlabs/geth-shardi…
nisdas Feb 18, 2020
dd096b5
raul's review
nisdas Feb 18, 2020
b0ebc75
Merge branch 'master' of https://github.com/prysmaticlabs/geth-shardi…
nisdas Feb 18, 2020
454113d
Merge refs/heads/master into OOMFix
prylabs-bulldozer[bot] Feb 18, 2020
18c5f27
fix refs
nisdas Feb 18, 2020
e0d1a26
Merge refs/heads/master into OOMFix
prylabs-bulldozer[bot] Feb 18, 2020
f1f571a
Merge refs/heads/master into OOMFix
prylabs-bulldozer[bot] Feb 18, 2020
1ea5d24
Merge branch 'master' of https://github.com/prysmaticlabs/geth-shardi…
nisdas Feb 18, 2020
e5ab1fc
terence's review
nisdas Feb 18, 2020
0276ea4
one more fix
nisdas Feb 18, 2020
2da4350
Update beacon-chain/blockchain/init_sync_process_block.go
terencechain Feb 18, 2020
8c67eed
Merge refs/heads/master into OOMFix
prylabs-bulldozer[bot] Feb 18, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions beacon-chain/blockchain/BUILD.bazel
Expand Up @@ -6,6 +6,7 @@ go_library(
"chain_info.go",
"head.go",
"info.go",
"init_sync_process_block.go",
"log.go",
"process_attestation.go",
"process_attestation_helpers.go",
Expand Down Expand Up @@ -37,6 +38,7 @@ go_library(
"//beacon-chain/p2p:go_default_library",
"//beacon-chain/powchain:go_default_library",
"//beacon-chain/state:go_default_library",
"//beacon-chain/stategen:go_default_library",
"//proto/beacon/p2p/v1:go_default_library",
"//shared/attestationutil:go_default_library",
"//shared/bytesutil:go_default_library",
Expand Down Expand Up @@ -67,6 +69,7 @@ go_test(
srcs = [
"chain_info_test.go",
"head_test.go",
"init_sync_process_block_test.go",
"process_attestation_test.go",
"process_block_test.go",
"receive_attestation_test.go",
Expand Down
184 changes: 184 additions & 0 deletions beacon-chain/blockchain/init_sync_process_block.go
@@ -0,0 +1,184 @@
package blockchain

import (
"context"
"sort"

"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/beacon-chain/stategen"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/params"
)

const maxCacheSize = 70
const initialSyncCacheSize = 45
const minimumCacheSize = initialSyncCacheSize / 3

func (s *Service) persistCachedStates(ctx context.Context, numOfStates int) error {
oldStates := make([]*stateTrie.BeaconState, 0, numOfStates)

// Add slots to the map and add epoch boundary states to the slice.
for _, rt := range s.boundaryRoots[:numOfStates-minimumCacheSize] {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this panic out of range?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if used normally without context , yes. But we only use it when we have len(s.boundaryRoots) > 45, so this will never happen in how it is currently used.

oldStates = append(oldStates, s.initSyncState[rt])
}

err := s.beaconDB.SaveStates(ctx, oldStates, s.boundaryRoots[:numOfStates-minimumCacheSize])
if err != nil {
return err
}
for _, rt := range s.boundaryRoots[:numOfStates-minimumCacheSize] {
delete(s.initSyncState, rt)
}
s.boundaryRoots = s.boundaryRoots[numOfStates-minimumCacheSize:]
return nil
}

// filter out boundary candidates from our currently processed batch of states.
func (s *Service) filterBoundaryCandidates(ctx context.Context, root [32]byte, postState *stateTrie.BeaconState) {
// Only trigger on epoch start.
if !helpers.IsEpochStart(postState.Slot()) {
return
}

stateSlice := make([][32]byte, 0, len(s.initSyncState))
// Add epoch boundary roots to slice.
for rt := range s.initSyncState {
stateSlice = append(stateSlice, rt)
}

sort.Slice(stateSlice, func(i int, j int) bool {
return s.initSyncState[stateSlice[i]].Slot() < s.initSyncState[stateSlice[j]].Slot()
})
epochLength := params.BeaconConfig().SlotsPerEpoch

if len(s.boundaryRoots) > 0 {
// Retrieve previous boundary root.
previousBoundaryRoot := s.boundaryRoots[len(s.boundaryRoots)-1]
previousSlot := s.initSyncState[previousBoundaryRoot].Slot()

// Round up slot number to account for skipped slots.
previousSlot = helpers.RoundUpToNearestEpoch(previousSlot)
if postState.Slot()-previousSlot > epochLength {
targetSlot := postState.Slot()
tempRoots := s.loopThroughCandidates(stateSlice, previousBoundaryRoot, previousSlot, targetSlot)
s.boundaryRoots = append(s.boundaryRoots, tempRoots...)
}
}
s.boundaryRoots = append(s.boundaryRoots, root)
s.pruneOldStates()
s.pruneNonBoundaryStates()
}

// loop-through the provided candidate roots to filter out which would be appropriate boundary roots.
func (s *Service) loopThroughCandidates(stateSlice [][32]byte, previousBoundaryRoot [32]byte,
previousSlot uint64, targetSlot uint64) [][32]byte {
tempRoots := [][32]byte{}
epochLength := params.BeaconConfig().SlotsPerEpoch

rauljordan marked this conversation as resolved.
Show resolved Hide resolved
// Loop through current states to filter for valid boundary states.
for i := len(stateSlice) - 1; stateSlice[i] != previousBoundaryRoot && i >= 0; i-- {
currentSlot := s.initSyncState[stateSlice[i]].Slot()
// Skip if the current slot is larger than the previous epoch
// boundary.
if currentSlot > targetSlot-epochLength {
continue
}
tempRoots = append(tempRoots, stateSlice[i])

// Switch target slot if the current slot is greater than
// 1 epoch boundary from the previously saved boundary slot.
if currentSlot > previousSlot+epochLength {
currentSlot = helpers.RoundUpToNearestEpoch(currentSlot)
targetSlot = currentSlot
continue
}
break
}
// Reverse to append the roots in ascending order corresponding
// to the respective slots.
tempRoots = bytesutil.ReverseBytes32Slice(tempRoots)
return tempRoots
}

// prune for states past the current finalized checkpoint.
func (s *Service) pruneOldStates() {
prunedBoundaryRoots := [][32]byte{}
for _, rt := range s.boundaryRoots {
st, ok := s.initSyncState[rt]
// Skip non-existent roots.
if !ok {
continue
}
if st.Slot() < helpers.StartSlot(s.FinalizedCheckpt().Epoch) {
delete(s.initSyncState, rt)
continue
}
prunedBoundaryRoots = append(prunedBoundaryRoots, rt)
}
s.boundaryRoots = prunedBoundaryRoots
}

// prune cache for non-boundary states.
func (s *Service) pruneNonBoundaryStates() {
boundaryMap := make(map[[32]byte]bool)
for i := range s.boundaryRoots {
boundaryMap[s.boundaryRoots[i]] = true
}
for rt := range s.initSyncState {
if !boundaryMap[rt] {
delete(s.initSyncState, rt)
}
}
}

func (s *Service) pruneOldNonFinalizedStates() {
stateSlice := make([][32]byte, 0, len(s.initSyncState))
// Add epoch boundary roots to slice.
for rt := range s.initSyncState {
stateSlice = append(stateSlice, rt)
}

// Sort by slots.
sort.Slice(stateSlice, func(i int, j int) bool {
return s.initSyncState[stateSlice[i]].Slot() < s.initSyncState[stateSlice[j]].Slot()
})

boundaryMap := make(map[[32]byte]bool)
for i := range s.boundaryRoots {
boundaryMap[s.boundaryRoots[i]] = true
}
for _, rt := range stateSlice[:initialSyncCacheSize] {
if boundaryMap[rt] {
continue
}
delete(s.initSyncState, rt)
}
}

func (s *Service) generateState(ctx context.Context, startRoot [32]byte, endRoot [32]byte) (*stateTrie.BeaconState, error) {
preState, err := s.beaconDB.State(ctx, startRoot)
if err != nil {
return nil, err
}
if preState == nil {
return nil, errors.New("finalized state does not exist in db")
}

endBlock, err := s.beaconDB.Block(ctx, endRoot)
if err != nil {
return nil, err
}
if endBlock == nil {
return nil, errors.New("provided block root does not have block saved in the db")
}
stGen := stategen.New(s.beaconDB)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you initialize this properly in node.go and pass it down to the service struct so stGen is part of *Service?


log.Warnf("Generating missing state of slot %d and root %#x", endBlock.Block.Slot, endRoot)
postState, err := stGen.GenerateState(ctx, preState, endBlock)
if err != nil {
return nil, errors.Wrapf(err, "could not generate state")
}
return postState, nil
}