Skip to content

Commit

Permalink
add uptime tracking to VM
Browse files Browse the repository at this point in the history
  • Loading branch information
ceyonur committed Sep 16, 2024
1 parent 0f16af2 commit 5f64be3
Show file tree
Hide file tree
Showing 6 changed files with 322 additions and 46 deletions.
2 changes: 1 addition & 1 deletion plugin/evm/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ func (b *Block) verify(predicateContext *precompileconfig.PredicateContext, writ
// If the chain is still bootstrapping, we can assume that all blocks we are verifying have
// been accepted by the network (so the predicate was validated by the network when the
// block was originally verified).
if b.vm.bootstrapped {
if b.vm.bootstrapped.Get() {
if err := b.verifyPredicates(predicateContext); err != nil {
return fmt.Errorf("failed to verify predicates: %w", err)
}
Expand Down
3 changes: 3 additions & 0 deletions plugin/evm/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ const (
// - state sync time: ~6 hrs.
defaultStateSyncMinBlocks = 300_000
defaultStateSyncRequestSize = 1024 // the number of key/values to ask peers for per request
defaultUptimeAPIEnabled = true
)

var (
Expand Down Expand Up @@ -88,6 +89,7 @@ type Config struct {

// Subnet EVM APIs
SnowmanAPIEnabled bool `json:"snowman-api-enabled"`
UptimeAPIEnabled bool `json:"uptime-api-enabled"`
AdminAPIEnabled bool `json:"admin-api-enabled"`
AdminAPIDir string `json:"admin-api-dir"`
WarpAPIEnabled bool `json:"warp-api-enabled"`
Expand Down Expand Up @@ -284,6 +286,7 @@ func (c *Config) SetDefaults() {
c.StateSyncRequestSize = defaultStateSyncRequestSize
c.AllowUnprotectedTxHashes = defaultAllowUnprotectedTxHashes
c.AcceptedCacheSize = defaultAcceptedCacheSize
c.UptimeAPIEnabled = defaultUptimeAPIEnabled
}

func (d *Duration) UnmarshalJSON(data []byte) (err error) {
Expand Down
97 changes: 97 additions & 0 deletions plugin/evm/mock_validator_state.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package evm

import (
"context"
"time"

"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/avalanchego/snow/validators"
"github.com/ava-labs/avalanchego/utils/crypto/bls"
)

var (
DefaultStartTime = uint64(time.Date(2024, time.July, 30, 0, 0, 0, 0, time.UTC).Unix())
DefaultSetWeightNonce = uint64(0)
DefaultIsActive = true
)

type ValidatorOutput struct {
NodeID ids.NodeID
VID ids.ID
IsActive bool
StartTime uint64
SetWeightNonce uint64
Weight uint64
BLSPublicKey *bls.PublicKey
}

type MockedValidatorState interface {
validators.State
// GetCurrentValidatorSet returns the current validator set for the provided subnet
// Returned map contains the ValidationID as the key and the ValidatorOutput as the value
GetCurrentValidatorSet(ctx context.Context, subnetID ids.ID) (map[ids.ID]*ValidatorOutput, error)
}

type recordedValidator struct {
StartTime uint64
SetWeightNonce uint64
IsActive bool
}

type MockValidatorState struct {
validators.State
recordedValidators map[ids.NodeID]recordedValidator
}

func NewMockValidatorState(pState validators.State) MockedValidatorState {
return &MockValidatorState{
State: pState,
recordedValidators: make(map[ids.NodeID]recordedValidator),
}
}

func (t *MockValidatorState) RecordValidator(nodeID ids.NodeID, startTime, setWeightNonce uint64) {
t.recordedValidators[nodeID] = recordedValidator{
StartTime: startTime,
SetWeightNonce: setWeightNonce,
IsActive: true,
}
}

func (t *MockValidatorState) GetCurrentValidatorSet(ctx context.Context, subnetID ids.ID) (map[ids.ID]*ValidatorOutput, error) {
currentPHeight, err := t.GetCurrentHeight(ctx)
if err != nil {
return nil, err
}
validatorSet, err := t.GetValidatorSet(ctx, currentPHeight, subnetID)
if err != nil {
return nil, err
}
output := make(map[ids.ID]*ValidatorOutput, len(validatorSet))
for key, value := range validatorSet {
startTime, isActive, setWeightNonce := DefaultStartTime, DefaultIsActive, DefaultSetWeightNonce
if recordedValidator, ok := t.recordedValidators[key]; ok {
startTime = recordedValidator.StartTime
isActive = recordedValidator.IsActive
setWeightNonce = recordedValidator.SetWeightNonce
}
// Converts the key to a validationID
// TODO: This is a temporary solution until we can use the correct ID type
validationID, err := ids.ToID(key.Bytes())
if err != nil {
return nil, err
}
output[validationID] = &ValidatorOutput{
NodeID: value.NodeID,
IsActive: isActive,
StartTime: startTime,
SetWeightNonce: setWeightNonce,
Weight: value.Weight,
BLSPublicKey: value.PublicKey,
}
}
return output, nil
}
30 changes: 30 additions & 0 deletions plugin/evm/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ package evm
import (
"context"
"math/big"
"time"

"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/avalanchego/snow"
"github.com/ava-labs/avalanchego/snow/uptime"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log"
)
Expand Down Expand Up @@ -36,3 +40,29 @@ func (api *SnowmanAPI) IssueBlock(ctx context.Context) error {
api.vm.builder.signalTxsReady()
return nil
}

type UptimeAPI struct {
ctx *snow.Context
calculator uptime.LockedCalculator
}

// TODO: add StartTime
type GetUptimeResponse struct {
NodeID ids.NodeID `json:"nodeID"`
Uptime time.Duration `json:"uptime"`
}

// GetUptime returns the uptime of the node
func (api *UptimeAPI) GetUptime(ctx context.Context, nodeID ids.NodeID) (*GetUptimeResponse, error) {
uptime, _, err := api.calculator.CalculateUptime(nodeID)
if err != nil {
return nil, err
}

return &GetUptimeResponse{
NodeID: nodeID,
Uptime: uptime,
}, nil
}

// TODO: add GetUptime for currently tracked peers
2 changes: 1 addition & 1 deletion plugin/evm/syncervm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,7 @@ func testSyncerVM(t *testing.T, vmSetup *syncVMSetup, test syncTest) {

// check we can transition to [NormalOp] state and continue to process blocks.
require.NoError(syncerVM.SetState(context.Background(), snow.NormalOp))
require.True(syncerVM.bootstrapped)
require.True(syncerVM.bootstrapped.Get())

// Generate blocks after we have entered normal consensus as well
generateAndAcceptBlocks(t, syncerVM, blocksToBuild, func(_ int, gen *core.BlockGen) {
Expand Down
Loading

0 comments on commit 5f64be3

Please sign in to comment.