Skip to content
This repository was archived by the owner on Dec 16, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 61 commits
Commits
Show all changes
97 commits
Select commit Hold shift + click to select a range
ce36343
add validator state
ceyonur Sep 16, 2024
549d319
add pausable uptime manager
ceyonur Sep 16, 2024
9987248
remove stuttering name
ceyonur Sep 16, 2024
e1ef744
Merge branch 'master' into validator-state
ceyonur Sep 16, 2024
b33ffbe
Merge branch 'validator-state' into pausable-uptime-manager
ceyonur Sep 16, 2024
0f16af2
rename state listener
ceyonur Sep 16, 2024
df3ce63
Merge branch 'validator-state' into pausable-uptime-manager
ceyonur Sep 16, 2024
5f64be3
add uptime tracking to VM
ceyonur Sep 16, 2024
6ff4954
remove unused param
ceyonur Sep 16, 2024
55927b2
add wg for update validators
ceyonur Sep 16, 2024
92fba2e
Merge branch 'pausable-uptime-manager' into uptime-tracking
ceyonur Sep 16, 2024
bdc2cc3
update state before network shutdown
ceyonur Sep 16, 2024
657e542
restart bootstrapping status in test
ceyonur Sep 16, 2024
9d6d40e
Merge branch 'uptime-tracking' of https://github.com/ava-labs/subnet-…
ceyonur Sep 16, 2024
9eaa3f3
add get validator to state
ceyonur Sep 17, 2024
66747f8
rename uptime to validator
ceyonur Sep 17, 2024
86a68c8
fix mock state
ceyonur Sep 17, 2024
f43bae2
tests
ceyonur Sep 18, 2024
92f6b7e
Update plugin/evm/validators/state.go
ceyonur Sep 19, 2024
0db2041
use update enum
ceyonur Sep 19, 2024
c5520bc
Update plugin/evm/validators/state.go
ceyonur Sep 19, 2024
dea94af
Update plugin/evm/validators/state.go
ceyonur Sep 19, 2024
c0f6ff4
respond to comments
ceyonur Sep 19, 2024
b7de0f6
Merge branch 'validator-state' of https://github.com/ava-labs/subnet-…
ceyonur Sep 19, 2024
b566103
update avalanchego dep branch
ceyonur Sep 19, 2024
66ab74b
update avalanchego dep branch
ceyonur Sep 19, 2024
ad3a35a
reviews
ceyonur Sep 19, 2024
64fe238
reword errs
ceyonur Sep 19, 2024
33d24d1
Merge branch 'pausable-uptime-manager' of https://github.com/ava-labs…
ceyonur Sep 19, 2024
d7338da
fix test changes
ceyonur Sep 19, 2024
8eab611
Merge branch 'master' into uptime-tracking-base
ceyonur Sep 19, 2024
9ad5528
fix upgrades after deactivating latest in context
ceyonur Sep 19, 2024
4536590
Merge branch 'uptime-tracking-base' into validator-state
ceyonur Sep 19, 2024
fc71949
Merge branch 'validator-state' into pausable-uptime-manager
ceyonur Sep 19, 2024
4304ac5
Merge branch 'pausable-uptime-manager' into uptime-tracking
ceyonur Sep 19, 2024
3225a32
use test branch from avalanchego
ceyonur Sep 20, 2024
df6ad02
use branch commit for ava version
ceyonur Sep 20, 2024
738003f
update e2e ava version
ceyonur Sep 20, 2024
29a501d
update avago dep
ceyonur Sep 20, 2024
71c7de0
remove extra line...
ceyonur Sep 20, 2024
cc6ce95
Merge branch 'master' into uptime-tracking-base
ceyonur Sep 20, 2024
bcd4c9c
Merge branch 'uptime-tracking-base' into validator-state
ceyonur Sep 20, 2024
a49dd8d
Merge branch 'validator-state' into pausable-uptime-manager
ceyonur Sep 20, 2024
27884f4
Merge branch 'pausable-uptime-manager' into uptime-tracking
ceyonur Sep 20, 2024
b9d6336
export struct
ceyonur Sep 26, 2024
734b201
Merge branch 'master' into validator-state
ceyonur Oct 28, 2024
3e94861
Merge branch 'validator-state' into pausable-uptime-manager
ceyonur Oct 28, 2024
cab1ddf
reviews
ceyonur Oct 29, 2024
d1a0ae8
Merge branch 'pausable-uptime-manager' into uptime-tracking
ceyonur Oct 29, 2024
5f8bf5b
conflict fix
ceyonur Oct 29, 2024
0ba2869
custom err msg
ceyonur Oct 29, 2024
374d885
add listener mock
ceyonur Oct 29, 2024
1fcca58
Merge branch 'master' into validator-state
ceyonur Oct 29, 2024
c41f39c
Merge branch 'validator-state' into pausable-uptime-manager
ceyonur Oct 29, 2024
f828d53
Merge branch 'pausable-uptime-manager' into uptime-tracking
ceyonur Oct 29, 2024
9e707ad
bump avago test branch
ceyonur Oct 29, 2024
cc73266
remove config
ceyonur Oct 29, 2024
8ef763f
remove api changes
ceyonur Oct 29, 2024
2a9da82
Revert "remove api changes"
ceyonur Oct 29, 2024
9a50ee8
use non-version db for validatorsDB
ceyonur Oct 29, 2024
58b9c35
Merge branch 'uptime-tracking' into uptime-tracking-api
ceyonur Oct 29, 2024
af39b2c
remove errs from resume and pause
ceyonur Oct 30, 2024
d5d3545
check after stopping
ceyonur Oct 30, 2024
6fffc2b
use expectedTime in tests
ceyonur Oct 31, 2024
4625f7c
reviews
ceyonur Oct 31, 2024
e1975cf
Update plugin/evm/vm.go
ceyonur Oct 31, 2024
74bd249
fix len
ceyonur Oct 31, 2024
e5ab9f2
Merge branch 'uptime-tracking' into uptime-tracking-api
ceyonur Oct 31, 2024
7c33221
Merge branch 'pausable-uptime-manager' into uptime-tracking
ceyonur Oct 31, 2024
733da4c
Merge branch 'master' into pausable-uptime-manager
ceyonur Nov 5, 2024
347055c
Merge branch 'pausable-uptime-manager' into uptime-tracking
ceyonur Nov 5, 2024
335d8bc
Merge branch 'uptime-tracking' into uptime-tracking-api
ceyonur Nov 5, 2024
2aebfe6
remove log
ceyonur Nov 5, 2024
25076c3
disable validators api by default
ceyonur Nov 5, 2024
d737c11
Merge branch 'master' into uptime-tracking
ceyonur Nov 5, 2024
6468d36
use interfaces from pkgs
ceyonur Nov 5, 2024
10c4bd4
improve comments
ceyonur Nov 6, 2024
9490aae
Merge branch 'uptime-tracking' into uptime-tracking-api
ceyonur Nov 6, 2024
fd462c5
Merge branch 'uptime-tracking-api' of https://github.com/ava-labs/sub…
ceyonur Nov 6, 2024
5974170
new fields and refactorings
ceyonur Nov 8, 2024
0388e84
Merge branch 'uptime-tracking' into uptime-tracking-api
ceyonur Nov 8, 2024
7dca70e
add new fields
ceyonur Nov 8, 2024
48ef70f
Merge branch 'master' into uptime-tracking
ceyonur Nov 8, 2024
424e7a7
fix linter
ceyonur Nov 8, 2024
4fa19b9
clarify comments
ceyonur Nov 8, 2024
4559ab9
Merge branch 'uptime-tracking' into uptime-tracking-api
ceyonur Nov 8, 2024
3d5261d
update comment
ceyonur Nov 8, 2024
a80c028
bump to poc branch
ceyonur Nov 9, 2024
a417614
Merge branch 'uptime-tracking' into uptime-tracking-api
ceyonur Nov 9, 2024
c39c7e0
enable validators API by default
ceyonur Nov 12, 2024
15886c1
reviews
ceyonur Nov 13, 2024
bf9b962
Merge branch 'master' into uptime-tracking
ceyonur Nov 13, 2024
ebaaefc
update comment
ceyonur Nov 13, 2024
3283e36
Merge branch 'uptime-tracking' into uptime-tracking-api
ceyonur Nov 13, 2024
a943b6f
update to avago master
ceyonur Nov 13, 2024
a8abbc3
Merge branch 'uptime-tracking' into uptime-tracking-api
ceyonur Nov 13, 2024
09c4401
Merge branch 'master' into uptime-tracking-api
ceyonur Nov 13, 2024
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
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ go 1.22.8
require (
github.com/VictoriaMetrics/fastcache v1.12.1
github.com/antithesishq/antithesis-sdk-go v0.3.8
github.com/ava-labs/avalanchego v1.11.13-0.20241026214739-acb3d7d102a0
github.com/ava-labs/avalanchego v1.11.13-0.20241029131257-e05aa37abaf9
github.com/cespare/cp v0.1.0
github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233
github.com/davecgh/go-spew v1.1.1
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ github.com/antithesishq/antithesis-sdk-go v0.3.8/go.mod h1:IUpT2DPAKh6i/YhSbt6Gl
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/ava-labs/avalanchego v1.11.13-0.20241026214739-acb3d7d102a0 h1:1T9OnvZP6XZ62EVWlfmrI8rrudyE6bM2Zt51pCHfS5o=
github.com/ava-labs/avalanchego v1.11.13-0.20241026214739-acb3d7d102a0/go.mod h1:gYlTU42Q4b29hzhUN22yclym5qwB3Si0jh4+LTn7DZM=
github.com/ava-labs/avalanchego v1.11.13-0.20241029131257-e05aa37abaf9 h1:rX5Xn5WBPppyvvZXp8wwx9dX+4fBY2/XeNIEm18ifzk=
github.com/ava-labs/avalanchego v1.11.13-0.20241029131257-e05aa37abaf9/go.mod h1:gYlTU42Q4b29hzhUN22yclym5qwB3Si0jh4+LTn7DZM=
github.com/ava-labs/coreth v0.13.8 h1:f14X3KgwHl9LwzfxlN6S4bbn5VA2rhEsNnHaRLSTo/8=
github.com/ava-labs/coreth v0.13.8/go.mod h1:t3BSv/eQv0AlDPMfEDCMMoD/jq1RkUsbFzQAFg5qBcE=
github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g=
Expand Down
38 changes: 38 additions & 0 deletions plugin/evm/api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package evm

import (
"context"
"math/big"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log"
)

// SnowmanAPI introduces snowman specific functionality to the evm
type SnowmanAPI struct{ vm *VM }

// GetAcceptedFrontReply defines the reply that will be sent from the
// GetAcceptedFront API call
type GetAcceptedFrontReply struct {
Hash common.Hash `json:"hash"`
Number *big.Int `json:"number"`
}

// GetAcceptedFront returns the last accepted block's hash and height
func (api *SnowmanAPI) GetAcceptedFront(ctx context.Context) (*GetAcceptedFrontReply, error) {
blk := api.vm.blockChain.LastConsensusAcceptedBlock()
return &GetAcceptedFrontReply{
Hash: blk.Hash(),
Number: blk.Number(),
}, nil
}

// IssueBlock to the chain
func (api *SnowmanAPI) IssueBlock(ctx context.Context) error {
log.Info("Issuing a new block")
api.vm.builder.signalTxsReady()
return nil
}
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
15 changes: 10 additions & 5 deletions plugin/evm/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,10 @@ const (
// - state sync time: ~6 hrs.
defaultStateSyncMinBlocks = 300_000
defaultStateSyncRequestSize = 1024 // the number of key/values to ask peers for per request
defaultDBType = pebbledb.Name

defaultValidatorsAPIEnabled = true

defaultDBType = pebbledb.Name
)

type PBool bool
Expand Down Expand Up @@ -91,10 +94,11 @@ type Config struct {
AirdropFile string `json:"airdrop"`

// Subnet EVM APIs
SnowmanAPIEnabled bool `json:"snowman-api-enabled"`
AdminAPIEnabled bool `json:"admin-api-enabled"`
AdminAPIDir string `json:"admin-api-dir"`
WarpAPIEnabled bool `json:"warp-api-enabled"`
SnowmanAPIEnabled bool `json:"snowman-api-enabled"`
ValidatorsAPIEnabled bool `json:"validators-api-enabled"`
AdminAPIEnabled bool `json:"admin-api-enabled"`
AdminAPIDir string `json:"admin-api-dir"`
WarpAPIEnabled bool `json:"warp-api-enabled"`

// EnabledEthAPIs is a list of Ethereum services that should be enabled
// If none is specified, then we use the default list [defaultEnabledAPIs]
Expand Down Expand Up @@ -296,6 +300,7 @@ func (c *Config) SetDefaults() {
c.StateSyncRequestSize = defaultStateSyncRequestSize
c.AllowUnprotectedTxHashes = defaultAllowUnprotectedTxHashes
c.AcceptedCacheSize = defaultAcceptedCacheSize
c.ValidatorsAPIEnabled = defaultValidatorsAPIEnabled
c.DatabaseType = defaultDBType
}

Expand Down
79 changes: 57 additions & 22 deletions plugin/evm/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,70 @@
package evm

import (
"context"
"math/big"
"net/http"
"time"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log"
"github.com/ava-labs/avalanchego/database"
"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/avalanchego/utils/set"
)

// SnowmanAPI introduces snowman specific functionality to the evm
type SnowmanAPI struct{ vm *VM }
type ValidatorsAPI struct {
vm *VM
}

type GetCurrentValidatorsRequest struct {
NodeIDs []ids.NodeID `json:"nodeIDs"`
}

// GetAcceptedFrontReply defines the reply that will be sent from the
// GetAcceptedFront API call
type GetAcceptedFrontReply struct {
Hash common.Hash `json:"hash"`
Number *big.Int `json:"number"`
type GetCurrentValidatorsResponse struct {
Validators []CurrentValidator `json:"validators"`
}

// GetAcceptedFront returns the last accepted block's hash and height
func (api *SnowmanAPI) GetAcceptedFront(ctx context.Context) (*GetAcceptedFrontReply, error) {
blk := api.vm.blockChain.LastConsensusAcceptedBlock()
return &GetAcceptedFrontReply{
Hash: blk.Hash(),
Number: blk.Number(),
}, nil
type CurrentValidator struct {
ValidationID ids.ID `json:"validationID"`
NodeID ids.NodeID `json:"nodeID"`
StartTime time.Time `json:"startTime"`
IsActive bool `json:"isActive"`
IsConnected bool `json:"isConnected"`
Uptime time.Duration `json:"uptime"`
}

// IssueBlock to the chain
func (api *SnowmanAPI) IssueBlock(ctx context.Context) error {
log.Info("Issuing a new block")
api.vm.builder.signalTxsReady()
func (api *ValidatorsAPI) GetCurrentValidators(_ *http.Request, args *GetCurrentValidatorsRequest, reply *GetCurrentValidatorsResponse) error {
api.vm.ctx.Lock.RLock()
defer api.vm.ctx.Lock.RUnlock()

nodeIDs := set.Of(args.NodeIDs...)
if nodeIDs.Len() == 0 {
nodeIDs = api.vm.validatorState.GetValidatorIDs()
}

reply.Validators = make([]CurrentValidator, 0, nodeIDs.Len())

for _, nodeID := range nodeIDs.List() {
validator, err := api.vm.validatorState.GetValidator(nodeID)
switch {
case err == database.ErrNotFound:
continue
case err != nil:
return err
}

isConnected := api.vm.uptimeManager.IsConnected(nodeID)

uptime, _, err := api.vm.uptimeManager.CalculateUptime(nodeID)
if err != nil {
return err
}

reply.Validators = append(reply.Validators, CurrentValidator{
ValidationID: validator.ValidationID,
NodeID: nodeID,
StartTime: validator.StartTime,
IsActive: validator.IsActive,
IsConnected: isConnected,
Uptime: time.Duration(uptime.Seconds()),
})
}
return nil
}
2 changes: 1 addition & 1 deletion plugin/evm/syncervm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,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
2 changes: 1 addition & 1 deletion plugin/evm/tx_gossip_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func TestEthTxGossip(t *testing.T) {
require := require.New(t)
ctx := context.Background()
snowCtx := utils.TestSnowContext()
validatorState := &validatorstest.State{}
validatorState := utils.NewTestValidatorState()
snowCtx.ValidatorState = validatorState

responseSender := &enginetest.SenderStub{
Expand Down
156 changes: 156 additions & 0 deletions plugin/evm/uptime/pausable_manager.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package uptime

import (
"errors"

"github.com/ava-labs/subnet-evm/plugin/evm/validators"
"github.com/ethereum/go-ethereum/log"

"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/avalanchego/snow/uptime"
"github.com/ava-labs/avalanchego/utils/set"
)

var _ validators.StateCallbackListener = &pausableManager{}

var (
errPausedDisconnect = errors.New("paused node cannot be disconnected")
errAlreadyPaused = errors.New("node is already paused")
errNotPaused = errors.New("node is not paused")
)

type PausableManager interface {
uptime.Manager
validators.StateCallbackListener
IsPaused(nodeID ids.NodeID) bool
}

type pausableManager struct {
uptime.Manager
pausedVdrs set.Set[ids.NodeID]
// connectedVdrs is a set of nodes that are connected to the manager.
// This is used to immediately connect nodes when they are unpaused.
connectedVdrs set.Set[ids.NodeID]
}

// NewPausableManager takes an uptime.Manager and returns a PausableManager
func NewPausableManager(manager uptime.Manager) PausableManager {
return &pausableManager{
pausedVdrs: make(set.Set[ids.NodeID]),
connectedVdrs: make(set.Set[ids.NodeID]),
Manager: manager,
}
}

// Connect connects the node with the given ID to the uptime.Manager
// If the node is paused, it will not be connected
func (p *pausableManager) Connect(nodeID ids.NodeID) error {
p.connectedVdrs.Add(nodeID)
if !p.IsPaused(nodeID) && !p.Manager.IsConnected(nodeID) {
return p.Manager.Connect(nodeID)
}
return nil
}

// Disconnect disconnects the node with the given ID from the uptime.Manager
// If the node is paused, it will not be disconnected
// Invariant: we should never have a connected paused node that is disconnecting
func (p *pausableManager) Disconnect(nodeID ids.NodeID) error {
p.connectedVdrs.Remove(nodeID)
if p.Manager.IsConnected(nodeID) {
if p.IsPaused(nodeID) {
// We should never see this case
return errPausedDisconnect
}
return p.Manager.Disconnect(nodeID)
}
return nil
}

// StartTracking starts tracking uptime for the nodes with the given IDs
// If a node is paused, it will not be tracked
func (p *pausableManager) StartTracking(nodeIDs []ids.NodeID) error {
var activeNodeIDs []ids.NodeID
for _, nodeID := range nodeIDs {
if !p.IsPaused(nodeID) {
activeNodeIDs = append(activeNodeIDs, nodeID)
}
}
return p.Manager.StartTracking(activeNodeIDs)
}

// OnValidatorAdded is called when a validator is added.
// If the node is inactive, it will be paused.
func (p *pausableManager) OnValidatorAdded(vID ids.ID, nodeID ids.NodeID, startTime uint64, isActive bool) {
if !isActive {
err := p.pause(nodeID)
if err != nil {
log.Error("failed to handle added validator %s: %s", nodeID, err)
}
}
}

// OnValidatorRemoved is called when a validator is removed.
// If the node is already paused, it will be resumed.
func (p *pausableManager) OnValidatorRemoved(vID ids.ID, nodeID ids.NodeID) {
if p.IsPaused(nodeID) {
err := p.resume(nodeID)
if err != nil {
log.Error("failed to handle validator removed %s: %s", nodeID, err)
}
}
}

// OnValidatorStatusUpdated is called when the status of a validator is updated.
// If the node is active, it will be resumed. If the node is inactive, it will be paused.
func (p *pausableManager) OnValidatorStatusUpdated(vID ids.ID, nodeID ids.NodeID, isActive bool) {
var err error
if isActive {
err = p.resume(nodeID)
} else {
err = p.pause(nodeID)
}
if err != nil {
log.Error("failed to update status for node %s: %s", nodeID, err)
}
}

// IsPaused returns true if the node with the given ID is paused.
func (p *pausableManager) IsPaused(nodeID ids.NodeID) bool {
return p.pausedVdrs.Contains(nodeID)
}

// pause pauses uptime tracking for the node with the given ID
// pause can disconnect the node from the uptime.Manager if it is connected.
// Returns an error if the node is already paused.
func (p *pausableManager) pause(nodeID ids.NodeID) error {
if p.IsPaused(nodeID) {
return errAlreadyPaused
}
p.pausedVdrs.Add(nodeID)
if p.Manager.IsConnected(nodeID) {
// If the node is connected, then we need to disconnect it from
// manager
// This should be fine in case tracking has not started yet since
// the inner manager should handle disconnects accordingly
return p.Manager.Disconnect(nodeID)
}
return nil
}

// resume resumes uptime tracking for the node with the given ID
// resume can connect the node to the uptime.Manager if it was connected.
// Returns an error if the node is not paused.
func (p *pausableManager) resume(nodeID ids.NodeID) error {
if !p.IsPaused(nodeID) {
return errNotPaused
}
p.pausedVdrs.Remove(nodeID)
if p.connectedVdrs.Contains(nodeID) && !p.Manager.IsConnected(nodeID) {
return p.Manager.Connect(nodeID)
}
return nil
}
Loading