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

Repackaged NextBlockTime and GetNextStakerChangeTime #3134

Merged
merged 2 commits into from
Jun 21, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions vms/platformvm/block/builder/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ func (b *builder) durationToSleep() (time.Duration, error) {
return 0, fmt.Errorf("%w: %s", errMissingPreferredState, preferredID)
}

nextStakerChangeTime, err := txexecutor.GetNextStakerChangeTime(preferredState)
nextStakerChangeTime, err := state.GetNextStakerChangeTime(preferredState)
if err != nil {
return 0, fmt.Errorf("%w of %s: %w", errCalculatingNextStakerTime, preferredID, err)
}
Expand Down Expand Up @@ -216,7 +216,7 @@ func (b *builder) BuildBlock(context.Context) (snowman.Block, error) {
return nil, fmt.Errorf("%w: %s", state.ErrMissingParentState, preferredID)
}

timestamp, timeWasCapped, err := txexecutor.NextBlockTime(preferredState, b.txExecutorBackend.Clk)
timestamp, timeWasCapped, err := state.NextBlockTime(preferredState, b.txExecutorBackend.Clk)
if err != nil {
return nil, fmt.Errorf("could not calculate next staker change time: %w", err)
}
Expand Down
2 changes: 1 addition & 1 deletion vms/platformvm/block/executor/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ func (m *manager) VerifyTx(tx *txs.Tx) error {
return err
}

nextBlkTime, _, err := executor.NextBlockTime(stateDiff, m.txExecutorBackend.Clk)
nextBlkTime, _, err := state.NextBlockTime(stateDiff, m.txExecutorBackend.Clk)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion vms/platformvm/block/executor/proposal_block_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1436,7 +1436,7 @@ func TestAddValidatorProposalBlock(t *testing.T) {

// Advance time until next staker change time is [validatorEndTime]
for {
nextStakerChangeTime, err := executor.GetNextStakerChangeTime(env.state)
nextStakerChangeTime, err := state.GetNextStakerChangeTime(env.state)
require.NoError(err)
if nextStakerChangeTime.Equal(validatorEndTime) {
break
Expand Down
2 changes: 1 addition & 1 deletion vms/platformvm/block/executor/verifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ func (v *verifier) banffNonOptionBlock(b block.BanffBlock) error {
)
}

nextStakerChangeTime, err := executor.GetNextStakerChangeTime(parentState)
nextStakerChangeTime, err := state.GetNextStakerChangeTime(parentState)
if err != nil {
return fmt.Errorf("could not verify block timestamp: %w", err)
}
Expand Down
70 changes: 70 additions & 0 deletions vms/platformvm/state/chain_time_helpers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package state

import (
"fmt"
"time"

"github.com/ava-labs/avalanchego/database"
"github.com/ava-labs/avalanchego/utils/timer/mockable"
)

func NextBlockTime(state Chain, clk *mockable.Clock) (time.Time, bool, error) {
var (
timestamp = clk.Time()
parentTime = state.GetTimestamp()
)
if parentTime.After(timestamp) {
timestamp = parentTime
}
// [timestamp] = max(now, parentTime)

nextStakerChangeTime, err := GetNextStakerChangeTime(state)
if err != nil {
return time.Time{}, false, fmt.Errorf("failed getting next staker change time: %w", err)
}

// timeWasCapped means that [timestamp] was reduced to [nextStakerChangeTime]
timeWasCapped := !timestamp.Before(nextStakerChangeTime)
if timeWasCapped {
timestamp = nextStakerChangeTime
}
// [timestamp] = min(max(now, parentTime), nextStakerChangeTime)
return timestamp, timeWasCapped, nil
}

// GetNextStakerChangeTime returns the next time a staker will be either added
// or removed to/from the current validator set.
func GetNextStakerChangeTime(state Chain) (time.Time, error) {
currentStakerIterator, err := state.GetCurrentStakerIterator()
if err != nil {
return time.Time{}, err
}
defer currentStakerIterator.Release()

pendingStakerIterator, err := state.GetPendingStakerIterator()
if err != nil {
return time.Time{}, err
}
defer pendingStakerIterator.Release()

hasCurrentStaker := currentStakerIterator.Next()
hasPendingStaker := pendingStakerIterator.Next()
switch {
case hasCurrentStaker && hasPendingStaker:
nextCurrentTime := currentStakerIterator.Value().NextTime
nextPendingTime := pendingStakerIterator.Value().NextTime
if nextCurrentTime.Before(nextPendingTime) {
return nextCurrentTime, nil
}
return nextPendingTime, nil
case hasCurrentStaker:
return currentStakerIterator.Value().NextTime, nil
case hasPendingStaker:
return pendingStakerIterator.Value().NextTime, nil
default:
return time.Time{}, database.ErrNotFound
}
}
2 changes: 1 addition & 1 deletion vms/platformvm/txs/executor/proposal_tx_executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ func (e *ProposalTxExecutor) AdvanceTimeTx(tx *txs.AdvanceTimeTx) error {

// Only allow timestamp to move forward as far as the time of next staker
// set change time
nextStakerChangeTime, err := GetNextStakerChangeTime(e.OnCommitState)
nextStakerChangeTime, err := state.GetNextStakerChangeTime(e.OnCommitState)
if err != nil {
return err
}
Expand Down
34 changes: 0 additions & 34 deletions vms/platformvm/txs/executor/staker_tx_verification_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,40 +94,6 @@ func getDelegatorRules(
}, nil
}

// GetNextStakerChangeTime returns the next time a staker will be either added
// or removed to/from the current validator set.
func GetNextStakerChangeTime(state state.Chain) (time.Time, error) {
currentStakerIterator, err := state.GetCurrentStakerIterator()
if err != nil {
return time.Time{}, err
}
defer currentStakerIterator.Release()

pendingStakerIterator, err := state.GetPendingStakerIterator()
if err != nil {
return time.Time{}, err
}
defer pendingStakerIterator.Release()

hasCurrentStaker := currentStakerIterator.Next()
hasPendingStaker := pendingStakerIterator.Next()
switch {
case hasCurrentStaker && hasPendingStaker:
nextCurrentTime := currentStakerIterator.Value().NextTime
nextPendingTime := pendingStakerIterator.Value().NextTime
if nextCurrentTime.Before(nextPendingTime) {
return nextCurrentTime, nil
}
return nextPendingTime, nil
case hasCurrentStaker:
return currentStakerIterator.Value().NextTime, nil
case hasPendingStaker:
return pendingStakerIterator.Value().NextTime, nil
default:
return time.Time{}, database.ErrNotFound
}
}

// GetValidator returns information about the given validator, which may be a
// current validator or pending validator.
func GetValidator(state state.Chain, subnetID ids.ID, nodeID ids.NodeID) (*state.Staker, error) {
Expand Down
25 changes: 0 additions & 25 deletions vms/platformvm/txs/executor/state_changes.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (

"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/avalanchego/utils/constants"
"github.com/ava-labs/avalanchego/utils/timer/mockable"
"github.com/ava-labs/avalanchego/vms/platformvm/reward"
"github.com/ava-labs/avalanchego/vms/platformvm/state"
"github.com/ava-labs/avalanchego/vms/platformvm/txs"
Expand Down Expand Up @@ -58,30 +57,6 @@ func VerifyNewChainTime(
return nil
}

func NextBlockTime(state state.Chain, clk *mockable.Clock) (time.Time, bool, error) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

NextBlockTime is the function we need to reuse e.g. in txBuilder package, when dynamic fees are activated.
We move it to state package to avoid circular dependencies and unlock compilation

var (
timestamp = clk.Time()
parentTime = state.GetTimestamp()
)
if parentTime.After(timestamp) {
timestamp = parentTime
}
// [timestamp] = max(now, parentTime)

nextStakerChangeTime, err := GetNextStakerChangeTime(state)
if err != nil {
return time.Time{}, false, fmt.Errorf("failed getting next staker change time: %w", err)
}

// timeWasCapped means that [timestamp] was reduced to [nextStakerChangeTime]
timeWasCapped := !timestamp.Before(nextStakerChangeTime)
if timeWasCapped {
timestamp = nextStakerChangeTime
}
// [timestamp] = min(max(now, parentTime), nextStakerChangeTime)
return timestamp, timeWasCapped, nil
}

// AdvanceTimeTo applies all state changes to [parentState] resulting from
// advancing the chain time to [newChainTime].
// Returns true iff the validator set changed.
Expand Down
Loading