Skip to content

Commit

Permalink
added support for whisk testnet (SSLE) #10
Browse files Browse the repository at this point in the history
  • Loading branch information
pk910 committed Aug 25, 2023
1 parent d084d26 commit 9f40ad6
Show file tree
Hide file tree
Showing 9 changed files with 182 additions and 64 deletions.
19 changes: 19 additions & 0 deletions db/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,25 @@ func GetBlockOrphanedRefs(blockRoots [][]byte) []*dbtypes.BlockOrphanedRef {
return orphanedRefs
}

func GetHighestRootBeforeSlot(slot uint64, withOrphaned bool) []byte {
result := &struct {
Root []byte `db:"root"`
}{}
orphanedLimit := ""
if !withOrphaned {
orphanedLimit = "AND NOT orphaned"
}

err := ReaderDb.Get(&result, `
SELECT root FROM blocks WHERE slot < $1 `+orphanedLimit+` ORDER BY slot DESC LIMIT 1
`, slot)
if err != nil {
logger.Errorf("Error while fetching highest root before %v: %v", slot, err)
return nil
}
return result.Root
}

func InsertUnfinalizedBlock(block *dbtypes.UnfinalizedBlock, tx *sqlx.Tx) error {
_, err := tx.Exec(EngineQuery(map[dbtypes.DBEngineType]string{
dbtypes.DBEnginePgsql: `
Expand Down
2 changes: 1 addition & 1 deletion indexer/cache_logic.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ func (cache *indexerCache) processFinalizedEpoch(epoch uint64) error {
var epochTarget []byte
var epochDependentRoot []byte
if firstBlock == nil {
logger.Warnf("counld not find epoch %v target (no block found)", epoch)
logger.Warnf("could not find epoch %v target (no block found)", epoch)
} else {
if firstBlock.Slot == firstSlot {
epochTarget = firstBlock.Root
Expand Down
67 changes: 42 additions & 25 deletions indexer/epoch_stats.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ package indexer
import (
"bytes"
"fmt"
"math"
"strconv"
"strings"
"sync"

"github.com/pk910/light-beaconchain-explorer/db"
"github.com/pk910/light-beaconchain-explorer/dbtypes"
"github.com/pk910/light-beaconchain-explorer/rpctypes"
"github.com/pk910/light-beaconchain-explorer/utils"
Expand Down Expand Up @@ -119,43 +121,48 @@ func (epochStats *EpochStats) GetSyncAssignments() []uint64 {
}

func (client *IndexerClient) ensureEpochStats(epoch uint64, head []byte) error {
var dependendRoot []byte
var dependentRoot []byte
var proposerRsp *rpctypes.StandardV1ProposerDutiesResponse
if epoch > 0 {
firstBlock := client.indexerCache.getFirstCanonicalBlock(epoch, head)
if firstBlock != nil {
logger.WithField("client", client.clientName).Debugf("canonical first block for epoch %v: %v/0x%x (head: 0x%x)", epoch, firstBlock.Slot, firstBlock.Root, head)
firstBlock.mutex.RLock()
if firstBlock.header != nil {
dependendRoot = firstBlock.header.Message.ParentRoot
dependentRoot = firstBlock.header.Message.ParentRoot
}
firstBlock.mutex.RUnlock()
}
if dependendRoot == nil {
if dependentRoot == nil {
lastBlock := client.indexerCache.getLastCanonicalBlock(epoch-1, head)
if lastBlock != nil {
logger.WithField("client", client.clientName).Debugf("canonical last block for epoch %v: %v/0x%x (head: 0x%x)", epoch-1, lastBlock.Slot, lastBlock.Root, head)
dependendRoot = lastBlock.Root
dependentRoot = lastBlock.Root
}
}
}
if dependendRoot == nil {
var err error
proposerRsp, err = client.rpcClient.GetProposerDuties(epoch)
if err != nil {
logger.WithField("client", client.clientName).Warnf("could not load proposer duties for epoch %v: %v", epoch, err)
}
if proposerRsp == nil {
return fmt.Errorf("could not find proposer duties for epoch %v", epoch)
if dependentRoot == nil {
if utils.Config.Chain.WhiskForkEpoch != nil && epoch >= *utils.Config.Chain.WhiskForkEpoch {
firstSlot := epoch * utils.Config.Chain.Config.SlotsPerEpoch
dependentRoot = db.GetHighestRootBeforeSlot(firstSlot, false)
} else {
var err error
proposerRsp, err = client.rpcClient.GetProposerDuties(epoch)
if err != nil {
logger.WithField("client", client.clientName).Warnf("could not load proposer duties for epoch %v: %v", epoch, err)
}
if proposerRsp == nil {
return fmt.Errorf("could not find proposer duties for epoch %v", epoch)
}
dependentRoot = proposerRsp.DependentRoot
}
dependendRoot = proposerRsp.DependentRoot
}

epochStats, isNewStats := client.indexerCache.createOrGetEpochStats(epoch, dependendRoot)
epochStats, isNewStats := client.indexerCache.createOrGetEpochStats(epoch, dependentRoot)
if isNewStats {
logger.WithField("client", client.clientName).Infof("load epoch stats for epoch %v (dependend: 0x%x)", epoch, dependendRoot)
logger.WithField("client", client.clientName).Infof("load epoch stats for epoch %v (dependend: 0x%x)", epoch, dependentRoot)
} else {
logger.WithField("client", client.clientName).Debugf("ensure epoch stats for epoch %v (dependend: 0x%x)", epoch, dependendRoot)
logger.WithField("client", client.clientName).Debugf("ensure epoch stats for epoch %v (dependend: 0x%x)", epoch, dependentRoot)
}
go epochStats.ensureEpochStatsLazy(client, proposerRsp)
if int64(epoch) > client.lastEpochStats {
Expand All @@ -175,7 +182,8 @@ func (epochStats *EpochStats) ensureEpochStatsLazy(client *IndexerClient, propos

// proposer duties
if epochStats.proposerAssignments == nil {
if proposerRsp == nil {
whiskActivated := utils.Config.Chain.WhiskForkEpoch != nil && epochStats.Epoch >= *utils.Config.Chain.WhiskForkEpoch
if proposerRsp == nil && !whiskActivated {
var err error
proposerRsp, err = client.rpcClient.GetProposerDuties(epochStats.Epoch)
if err != nil {
Expand All @@ -191,8 +199,16 @@ func (epochStats *EpochStats) ensureEpochStatsLazy(client *IndexerClient, propos
}
}
epochStats.proposerAssignments = map[uint64]uint64{}
for _, duty := range proposerRsp.Data {
epochStats.proposerAssignments[uint64(duty.Slot)] = uint64(duty.ValidatorIndex)
if whiskActivated {
firstSlot := epochStats.Epoch * utils.Config.Chain.Config.SlotsPerEpoch
lastSlot := firstSlot + utils.Config.Chain.Config.SlotsPerEpoch - 1
for slot := firstSlot; slot <= lastSlot; slot++ {
epochStats.proposerAssignments[slot] = math.MaxInt64
}
} else {
for _, duty := range proposerRsp.Data {
epochStats.proposerAssignments[uint64(duty.Slot)] = uint64(duty.ValidatorIndex)
}
}
}

Expand All @@ -210,19 +226,20 @@ func (epochStats *EpochStats) ensureEpochStatsLazy(client *IndexerClient, propos
}
} else {
parsedHeader, err := client.rpcClient.GetBlockHeaderByBlockroot(epochStats.DependentRoot)
if err != nil {
if err != nil || parsedHeader == nil {
logger.WithField("client", client.clientName).Warnf("could not get dependent block header for epoch %v (0x%x)", epochStats.Epoch, epochStats.DependentRoot)
}
if parsedHeader.Data.Header.Message.Slot == 0 {
epochStats.dependentStateRef = "genesis"
} else {
epochStats.dependentStateRef = parsedHeader.Data.Header.Message.StateRoot.String()
if parsedHeader.Data.Header.Message.Slot == 0 {
epochStats.dependentStateRef = "genesis"
} else {
epochStats.dependentStateRef = parsedHeader.Data.Header.Message.StateRoot.String()
}
}
}
}

// load validators
if epochStats.validatorStats == nil {
if epochStats.validatorStats == nil && epochStats.dependentStateRef != "" {
go epochStats.ensureValidatorStatsLazy(client, epochStats.dependentStateRef)
}

Expand Down
9 changes: 8 additions & 1 deletion indexer/indexer.go
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,13 @@ func (indexer *Indexer) GetCachedBlocksByParentRoot(parentRoot []byte) []*CacheB
return resBlocks
}

func (indexer *Indexer) GetFirstCachedCanonicalBlock(epoch uint64, head []byte) *CacheBlock {
indexer.indexerCache.cacheMutex.RLock()
defer indexer.indexerCache.cacheMutex.RUnlock()
block := indexer.indexerCache.getFirstCanonicalBlock(epoch, head)
return block
}

func (indexer *Indexer) GetCachedEpochStats(epoch uint64) *EpochStats {
_, headRoot := indexer.GetCanonicalHead()
return indexer.getCachedEpochStats(epoch, headRoot)
Expand Down Expand Up @@ -369,7 +376,7 @@ func (indexer *Indexer) getEpochVotes(epoch uint64, epochStats *EpochStats) *Epo
firstBlock := indexer.indexerCache.getFirstCanonicalBlock(epoch, headRoot)
var epochTarget []byte
if firstBlock == nil {
logger.Warnf("Counld not find epoch %v target (no block found)", epoch)
logger.Warnf("could not find epoch %v target (no block found)", epoch)
} else {
if firstBlock.Slot == firstSlot {
epochTarget = firstBlock.Root
Expand Down
47 changes: 25 additions & 22 deletions indexer/synchronizer.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,22 +156,10 @@ func (sync *synchronizerState) syncEpoch(syncEpoch uint64, lastTry bool, skipCli

client := sync.indexer.GetReadyClient(true, nil, skipClients)

// load epoch assignments
epochAssignments, err := client.rpcClient.GetEpochAssignments(syncEpoch)
if err != nil || epochAssignments == nil {
return false, client, fmt.Errorf("error fetching epoch %v duties: %v", syncEpoch, err)
}
if epochAssignments.AttestorAssignments == nil && !lastTry {
return false, client, fmt.Errorf("error fetching epoch %v duties: attestor assignments empty", syncEpoch)
}

if sync.checkKillChan(0) {
return false, nil, nil
}

// load headers & blocks from this & next epoch
firstSlot := syncEpoch * utils.Config.Chain.Config.SlotsPerEpoch
lastSlot := firstSlot + (utils.Config.Chain.Config.SlotsPerEpoch * 2) - 1
var firstBlock *CacheBlock
for slot := firstSlot; slot <= lastSlot; slot++ {
if sync.cachedSlot >= slot {
continue
Expand All @@ -196,13 +184,37 @@ func (sync *synchronizerState) syncEpoch(syncEpoch uint64, lastTry bool, skipCli
header: &headerRsp.Data.Header,
block: &blockRsp.Data,
}
if firstBlock == nil {
firstBlock = sync.cachedBlocks[slot]
}
}
sync.cachedSlot = lastSlot

if sync.checkKillChan(0) {
return false, nil, nil
}

// load epoch assignments
var dependentRoot []byte
if firstBlock != nil {
dependentRoot = firstBlock.header.Message.ParentRoot
} else {
// get from db
dependentRoot = db.GetHighestRootBeforeSlot(firstSlot, false)
}

epochAssignments, err := client.rpcClient.GetEpochAssignments(syncEpoch, dependentRoot)
if err != nil || epochAssignments == nil {
return false, client, fmt.Errorf("error fetching epoch %v duties: %v", syncEpoch, err)
}
if epochAssignments.AttestorAssignments == nil && !lastTry {
return false, client, fmt.Errorf("error fetching epoch %v duties: attestor assignments empty", syncEpoch)
}

if sync.checkKillChan(0) {
return false, nil, nil
}

// load epoch stats
epochStats := &EpochStats{
Epoch: syncEpoch,
Expand All @@ -221,15 +233,6 @@ func (sync *synchronizerState) syncEpoch(syncEpoch uint64, lastTry bool, skipCli
}

// process epoch vote aggregations
var firstBlock *CacheBlock
lastSlot = firstSlot + (utils.Config.Chain.Config.SlotsPerEpoch) - 1
for slot := firstSlot; slot <= lastSlot; slot++ {
if sync.cachedBlocks[slot] != nil {
firstBlock = sync.cachedBlocks[slot]
break
}
}

var targetRoot []byte
if firstBlock != nil {
if uint64(firstBlock.header.Message.Slot) == firstSlot {
Expand Down
Loading

0 comments on commit 9f40ad6

Please sign in to comment.