Skip to content

Commit

Permalink
chore: update validator nonces in endblocker (#1292)
Browse files Browse the repository at this point in the history
# Related Github tickets

- VolumeFi#2160

# Background

The way it was before, we would need a claim to be observed so
validators would be updated. By doing it in the endblocker, we
validators are always up-to-date.

This should prevent a situation where the last claim is 19, the last
observed nonce is 18, but validators are stuck on nonce 17. They would
receive a list of block events with the block of nonce 19 (latest
unobserved) but would be unable to claim it, since skyway would expect
them to submit a claim for nonce 18 instead.

# Testing completed

- [ ] test coverage exists or has been added/updated
- [x] tested in a private testnet

# Breaking changes

- [x] I have checked my code for breaking changes
- [x] If there are breaking changes, there is a supporting migration.
  • Loading branch information
maharifu committed Sep 13, 2024
1 parent 45bcb4e commit d4d89dd
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 14 deletions.
15 changes: 15 additions & 0 deletions x/skyway/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,12 @@ import (
"github.com/palomachain/paloma/x/skyway/types"
)

const updateValidatorNoncesPeriod = 50

// EndBlocker is called at the end of every block
func EndBlocker(ctx context.Context, k keeper.Keeper, cc *libcons.ConsensusChecker) {
sdkCtx := sdk.UnwrapSDKContext(ctx)

logger := liblog.FromKeeper(ctx, k).WithComponent("skyway-endblocker")
defer func() {
if r := recover(); r != nil {
Expand All @@ -42,6 +46,17 @@ func EndBlocker(ctx context.Context, k keeper.Keeper, cc *libcons.ConsensusCheck
if err != nil {
logger.WithError(err).Warn("Failed to prune attestations.")
}

if sdkCtx.BlockHeight()%updateValidatorNoncesPeriod == 0 {
// Update all validator nonces to the latest observed nonce, if
// suitable This makes sure validators don't get stuck waiting for
// events they can't get from the RPC, even though these events are
// already observed
err = k.UpdateValidatorNoncesToLatest(ctx, v)
if err != nil {
logger.WithError(err).Warn("Failed to update validator nonces.")
}
}
}

err = processGasEstimates(ctx, k, cc)
Expand Down
7 changes: 0 additions & 7 deletions x/skyway/keeper/attestation.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,13 +165,6 @@ func (k Keeper) TryAttestation(ctx context.Context, att *types.Attestation) erro
return err
}

// Update all validator nonces to the claim nonce that was just
// processed
err = k.updateValidatorNoncesIfHigher(ctx, claim.GetChainReferenceId(), claim.GetSkywayNonce())
if err != nil {
return err
}

break
}
}
Expand Down
19 changes: 12 additions & 7 deletions x/skyway/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -481,21 +481,26 @@ func (k Keeper) overrideNonce(ctx context.Context, chainReferenceId string, nonc
return nil
}

// updateValidatorNoncesIfHigher updates all validator nonces to `newNonce` only
// if it is higher than the current record
func (k Keeper) updateValidatorNoncesIfHigher(
// UpdateValidatorNoncesToLatest updates all validator nonces to the last
// observed skyway nonce only if it is higher than the current record
func (k Keeper) UpdateValidatorNoncesToLatest(
ctx context.Context,
chainReferenceId string,
newNonce uint64,
) error {
logger := liblog.FromKeeper(ctx, k).WithComponent("update-validator-nonces-if-higher")

lastSkywayNonce, err := k.GetLastObservedSkywayNonce(ctx, chainReferenceId)
if err != nil {
logger.WithError(err).Warn("Failed to get last observed nonce.")
return err
}

store := k.GetStore(ctx, chainReferenceId)
prefixStore := prefix.NewStore(store, types.LastEventNonceByValidatorKey)

err := k.IterateValidatorLastEventNonces(ctx, chainReferenceId, func(key []byte, nonce uint64) bool {
if newNonce > nonce {
prefixStore.Set(key, types.UInt64Bytes(newNonce))
err = k.IterateValidatorLastEventNonces(ctx, chainReferenceId, func(key []byte, nonce uint64) bool {
if lastSkywayNonce > nonce {
prefixStore.Set(key, types.UInt64Bytes(lastSkywayNonce))
}

return false
Expand Down

0 comments on commit d4d89dd

Please sign in to comment.