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

[PVM] Adjustment of validator uptime on reactivation #189

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
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
13 changes: 12 additions & 1 deletion vms/platformvm/state/camino.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,10 @@ type CaminoDiff interface {
PutDeferredValidator(staker *Staker)
DeleteDeferredValidator(staker *Staker)
GetDeferredStakerIterator() (StakerIterator, error)

// Validators uptime

SetValidatorUptime(subnetID ids.ID, node ids.NodeID, uptime time.Duration)
}

// For state and diff
Expand Down Expand Up @@ -151,11 +155,14 @@ type caminoDiff struct {
modifiedShortLinks map[ids.ID]*ids.ShortID
modifiedClaimables map[ids.ID]*Claimable
modifiedNotDistributedValidatorReward *uint64
modifiedUptimes map[ids.NodeID]map[ids.ID]time.Duration
}

type caminoState struct {
*caminoDiff

state *state

caminoDB database.Database
genesisSynced bool
verifyNodeSignature bool
Expand Down Expand Up @@ -203,10 +210,11 @@ func newCaminoDiff() *caminoDiff {
modifiedMultisigAliases: make(map[ids.ShortID]*multisig.AliasWithNonce),
modifiedShortLinks: make(map[ids.ID]*ids.ShortID),
modifiedClaimables: make(map[ids.ID]*Claimable),
modifiedUptimes: make(map[ids.NodeID]map[ids.ID]time.Duration),
}
}

func newCaminoState(baseDB, validatorsDB database.Database, metricsReg prometheus.Registerer) (*caminoState, error) {
func newCaminoState(state *state, baseDB, validatorsDB database.Database, metricsReg prometheus.Registerer) (*caminoState, error) {
addressStateCache, err := metercacher.New[ids.ShortID, uint64](
"address_state_cache",
metricsReg,
Expand Down Expand Up @@ -255,6 +263,8 @@ func newCaminoState(baseDB, validatorsDB database.Database, metricsReg prometheu
deferredValidatorsDB := prefixdb.New(deferredPrefix, validatorsDB)

return &caminoState{
state: state,

// Address State
addressStateDB: prefixdb.New(addressStatePrefix, baseDB),
addressStateCache: addressStateCache,
Expand Down Expand Up @@ -515,6 +525,7 @@ func (cs *caminoState) Write() error {
cs.writeShortLinks(),
cs.writeClaimableAndValidatorRewards(),
cs.writeDeferredStakers(),
cs.writeValidatorUptimes(),
)
return errs.Err
}
Expand Down
13 changes: 13 additions & 0 deletions vms/platformvm/state/camino_diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,13 @@ func (d *diff) GetDeferredStakerIterator() (StakerIterator, error) {
return d.caminoDiff.deferredStakerDiffs.GetStakerIterator(parentIterator), nil
}

func (d *diff) SetValidatorUptime(subnetID ids.ID, nodeID ids.NodeID, uptime time.Duration) {
if d.caminoDiff.modifiedUptimes[nodeID] == nil {
d.caminoDiff.modifiedUptimes[nodeID] = make(map[ids.ID]time.Duration)
}
d.caminoDiff.modifiedUptimes[nodeID][subnetID] = uptime
}

// Finally apply all changes
func (d *diff) ApplyCaminoState(baseState State) {
if d.caminoDiff.modifiedNotDistributedValidatorReward != nil {
Expand Down Expand Up @@ -437,4 +444,10 @@ func (d *diff) ApplyCaminoState(baseState State) {
}
}
}

for nodeID, subnetMap := range d.caminoDiff.modifiedUptimes {
for subnetID, uptime := range subnetMap {
baseState.SetValidatorUptime(subnetID, nodeID, uptime)
}
}
}
22 changes: 21 additions & 1 deletion vms/platformvm/state/camino_stakers.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ package state

import (
"fmt"
"time"

"github.com/ava-labs/avalanchego/database"

"github.com/ava-labs/avalanchego/database/linkeddb"
"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/avalanchego/vms/platformvm/txs"
Expand Down Expand Up @@ -102,3 +102,23 @@ func writeDeferredDiff(
}
return nil
}

func (cs *caminoState) SetValidatorUptime(subnetID ids.ID, nodeID ids.NodeID, uptime time.Duration) {
if cs.modifiedUptimes[nodeID] == nil {
cs.modifiedUptimes[nodeID] = make(map[ids.ID]time.Duration)
}
cs.modifiedUptimes[nodeID][subnetID] = uptime
}

func (cs *caminoState) writeValidatorUptimes() error {
charalarg marked this conversation as resolved.
Show resolved Hide resolved
for nodeID, uptimes := range cs.modifiedUptimes {
for subnetID, uptime := range uptimes {
err := cs.state.SetUptime(nodeID, subnetID, uptime, time.Now())
if err != nil {
return err
}
delete(cs.modifiedUptimes[nodeID], subnetID)
}
}
return nil
}
8 changes: 8 additions & 0 deletions vms/platformvm/state/camino_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ import (
"github.com/ava-labs/avalanchego/vms/platformvm/locked"
)

func (s *state) CaminoState() (CaminoState, error) {
return s.caminoState, nil
}

func (s *state) LockedUTXOs(txIDs set.Set[ids.ID], addresses set.Set[ids.ShortID], lockState locked.State) ([]*avax.UTXO, error) {
retUtxos := []*avax.UTXO{}
for address := range addresses {
Expand Down Expand Up @@ -139,3 +143,7 @@ func (s *state) DeleteDeferredValidator(staker *Staker) {
func (s *state) GetDeferredStakerIterator() (StakerIterator, error) {
return s.caminoState.GetDeferredStakerIterator()
}

func (s *state) SetValidatorUptime(subnetID ids.ID, nodeID ids.NodeID, uptime time.Duration) {
s.caminoState.SetValidatorUptime(subnetID, nodeID, uptime)
}
46 changes: 35 additions & 11 deletions vms/platformvm/state/camino_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,26 @@ import (
"testing"
"time"

"github.com/golang/mock/gomock"
"github.com/prometheus/client_golang/prometheus"
"github.com/stretchr/testify/require"

"github.com/ava-labs/avalanchego/cache"
"github.com/ava-labs/avalanchego/cache/metercacher"
"github.com/ava-labs/avalanchego/database/manager"
"github.com/ava-labs/avalanchego/database/prefixdb"
"github.com/ava-labs/avalanchego/database/versiondb"
root_genesis "github.com/ava-labs/avalanchego/genesis"
"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/avalanchego/utils/units"
"github.com/ava-labs/avalanchego/utils/wrappers"
"github.com/ava-labs/avalanchego/version"
"github.com/ava-labs/avalanchego/vms/components/avax"
"github.com/ava-labs/avalanchego/vms/platformvm/deposit"
pvm_genesis "github.com/ava-labs/avalanchego/vms/platformvm/genesis"
"github.com/ava-labs/avalanchego/vms/platformvm/reward"
"github.com/ava-labs/avalanchego/vms/platformvm/txs"
"github.com/ava-labs/avalanchego/vms/secp256k1fx"
"github.com/golang/mock/gomock"
"github.com/prometheus/client_golang/prometheus"
"github.com/stretchr/testify/require"

db_manager "github.com/ava-labs/avalanchego/database/manager"
root_genesis "github.com/ava-labs/avalanchego/genesis"
pvm_genesis "github.com/ava-labs/avalanchego/vms/platformvm/genesis"
)

const (
Expand Down Expand Up @@ -167,10 +169,9 @@ func TestSyncGenesis(t *testing.T) {
require := require.New(t)
ctrl := gomock.NewController(t)
defer ctrl.Finish()
s, _ := newInitializedState(require)
baseDBManager := db_manager.NewMemDB(version.Semantic1_0_0)
baseDBManager := manager.NewMemDB(version.CurrentDatabase)
baseDB := versiondb.New(baseDBManager.Current().Database)
validatorsDB := prefixdb.New(validatorsPrefix, baseDB)
s, _ := newInitializedState(require)

var (
id = ids.GenerateTestID()
Expand Down Expand Up @@ -232,6 +233,20 @@ func TestSyncGenesis(t *testing.T) {

depositTxs := []*txs.Tx{depositTx1, depositTx2}

prometheusRegistry := prometheus.NewRegistry()
addressStateCache, err := metercacher.New[ids.ShortID, uint64](
"address_state_cache",
prometheusRegistry,
&cache.LRU[ids.ShortID, uint64]{Size: addressStateCacheSize},
)
require.NoError(err)
depositsCache, err := metercacher.New[ids.ID, *deposit.Deposit](
"deposits_cache",
prometheusRegistry,
&cache.LRU[ids.ID, *deposit.Deposit]{Size: depositsCacheSize},
)
require.NoError(err)

type args struct {
s *state
g *pvm_genesis.State
Expand All @@ -256,7 +271,16 @@ func TestSyncGenesis(t *testing.T) {
},
}, depositTxs, initialAdmin),
},
cs: *wrappers.IgnoreError(newCaminoState(baseDB, validatorsDB, prometheus.NewRegistry())).(*caminoState),
cs: caminoState{
depositsDB: prefixdb.New(depositsPrefix, baseDB),
caminoDiff: &caminoDiff{
modifiedAddressStates: map[ids.ShortID]uint64{},
modifiedDepositOffers: map[ids.ID]*deposit.Offer{},
modifiedDeposits: map[ids.ID]*depositDiff{},
},
addressStateCache: addressStateCache,
depositsCache: depositsCache,
},
want: caminoDiff{
modifiedAddressStates: map[ids.ShortID]uint64{initialAdmin: txs.AddressStateRoleAdminBit, shortID: txs.AddressStateRoleKycBit},
modifiedDepositOffers: map[ids.ID]*deposit.Offer{
Expand Down
27 changes: 27 additions & 0 deletions vms/platformvm/state/mock_chain.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 27 additions & 0 deletions vms/platformvm/state/mock_diff.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 27 additions & 0 deletions vms/platformvm/state/mock_state.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 10 additions & 9 deletions vms/platformvm/state/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -498,12 +498,7 @@ func new(
return nil, err
}

caminoState, err := newCaminoState(baseDB, validatorsDB, metricsReg)
if err != nil {
return nil, err
}

return &state{
state := state{
charalarg marked this conversation as resolved.
Show resolved Hide resolved
validatorUptimes: newValidatorUptimes(),

cfg: cfg,
Expand All @@ -520,8 +515,6 @@ func new(
currentStakers: newBaseStakers(),
pendingStakers: newBaseStakers(),

caminoState: caminoState,

validatorsDB: validatorsDB,
currentValidatorsDB: currentValidatorsDB,
currentValidatorBaseDB: currentValidatorBaseDB,
Expand Down Expand Up @@ -575,7 +568,15 @@ func new(
chainDBCache: chainDBCache,

singletonDB: prefixdb.New(singletonPrefix, baseDB),
}, nil
}

caminoState, err := newCaminoState(&state, baseDB, validatorsDB, metricsReg)
if err != nil {
return nil, err
}
state.caminoState = caminoState

return &state, nil
}

func (s *state) GetCurrentValidator(subnetID ids.ID, nodeID ids.NodeID) (*Staker, error) {
Expand Down
1 change: 1 addition & 0 deletions vms/platformvm/txs/executor/camino_tx_executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -1456,6 +1456,7 @@ func (e *CaminoStandardTxExecutor) AddressStateTx(tx *txs.AddressStateTx) error
}
e.State.DeleteDeferredValidator(stakerToReactivate)
e.State.PutCurrentValidator(stakerToReactivate)
e.State.SetValidatorUptime(constants.PrimaryNetworkID, nodeID, e.Clk.Time().Sub(stakerToReactivate.StartTime))
} else {
// transfer staker to from current to deferred stakers set
stakerToDefer, err := e.State.GetCurrentValidator(constants.PrimaryNetworkID, nodeID)
Expand Down