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

Add support for dynamic network definitions #18

Merged
merged 13 commits into from
Jul 25, 2024
Merged
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
6 changes: 3 additions & 3 deletions api/server/queryless.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func RegisterQuerylessGet[ContextType IQuerylessCallContext[DataType], DataType
functionName string,
factory IQuerylessGetContextFactory[ContextType, DataType],
logger *slog.Logger,
serviceProvider *services.ServiceProvider,
serviceProvider services.IServiceProvider,
) {
router.HandleFunc(fmt.Sprintf("/%s", functionName), func(w http.ResponseWriter, r *http.Request) {
// Log
Expand Down Expand Up @@ -91,7 +91,7 @@ func RegisterQuerylessPost[ContextType IQuerylessCallContext[DataType], BodyType
functionName string,
factory IQuerylessPostContextFactory[ContextType, BodyType, DataType],
logger *slog.Logger,
serviceProvider *services.ServiceProvider,
serviceProvider services.IServiceProvider,
) {
router.HandleFunc(fmt.Sprintf("/%s", functionName), func(w http.ResponseWriter, r *http.Request) {
// Log
Expand Down Expand Up @@ -148,7 +148,7 @@ func RegisterQuerylessPost[ContextType IQuerylessCallContext[DataType], BodyType
}

// Run a route registered with no structured chain query pattern
func runQuerylessRoute[DataType any](ctx IQuerylessCallContext[DataType], serviceProvider *services.ServiceProvider) (types.ResponseStatus, *types.ApiResponse[DataType], error) {
func runQuerylessRoute[DataType any](ctx IQuerylessCallContext[DataType], serviceProvider services.IServiceProvider) (types.ResponseStatus, *types.ApiResponse[DataType], error) {
// Get the services
w := serviceProvider.GetWallet()

Expand Down
6 changes: 3 additions & 3 deletions api/server/single-stage.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func RegisterSingleStageRoute[ContextType ISingleStageCallContext[DataType], Dat
functionName string,
factory ISingleStageGetContextFactory[ContextType, DataType],
logger *slog.Logger,
serviceProvider *services.ServiceProvider,
serviceProvider services.IServiceProvider,
) {
router.HandleFunc(fmt.Sprintf("/%s", functionName), func(w http.ResponseWriter, r *http.Request) {
// Log
Expand Down Expand Up @@ -95,7 +95,7 @@ func RegisterSingleStagePost[ContextType ISingleStageCallContext[DataType], Body
functionName string,
factory ISingleStagePostContextFactory[ContextType, BodyType, DataType],
logger *slog.Logger,
serviceProvider *services.ServiceProvider,
serviceProvider services.IServiceProvider,
) {
router.HandleFunc(fmt.Sprintf("/%s", functionName), func(w http.ResponseWriter, r *http.Request) {
// Log
Expand Down Expand Up @@ -152,7 +152,7 @@ func RegisterSingleStagePost[ContextType ISingleStageCallContext[DataType], Body
}

// Run a route registered with the common single-stage querying pattern
func runSingleStageRoute[DataType any](ctx ISingleStageCallContext[DataType], serviceProvider *services.ServiceProvider) (types.ResponseStatus, *types.ApiResponse[DataType], error) {
func runSingleStageRoute[DataType any](ctx ISingleStageCallContext[DataType], serviceProvider services.IServiceProvider) (types.ResponseStatus, *types.ApiResponse[DataType], error) {
// Get the services
w := serviceProvider.GetWallet()
q := serviceProvider.GetQueryManager()
Expand Down
7 changes: 4 additions & 3 deletions beacon/client/committees.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ import (
"sync"

"github.com/goccy/go-json"
"github.com/rocket-pool/node-manager-core/utils"
)

type Committee struct {
Index Uinteger `json:"index"`
Slot Uinteger `json:"slot"`
Validators []string `json:"validators"`
Index utils.Uinteger `json:"index"`
Slot utils.Uinteger `json:"slot"`
Validators []string `json:"validators"`
}

// Custom deserialization logic for Committee allows us to pool the validator
Expand Down
2 changes: 1 addition & 1 deletion beacon/client/std-client.go
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@ func (c *StandardClient) GetDomainData(ctx context.Context, domainType []byte, e
func (c *StandardClient) ExitValidator(ctx context.Context, validatorIndex string, epoch uint64, signature beacon.ValidatorSignature) error {
return c.provider.Beacon_VoluntaryExits_Post(ctx, VoluntaryExitRequest{
Message: VoluntaryExitMessage{
Epoch: Uinteger(epoch),
Epoch: utils.Uinteger(epoch),
ValidatorIndex: validatorIndex,
},
Signature: signature[:],
Expand Down
153 changes: 49 additions & 104 deletions beacon/client/types.go
Original file line number Diff line number Diff line change
@@ -1,79 +1,76 @@
package client

import (
"strconv"

"github.com/ethereum/go-ethereum/common"
"github.com/goccy/go-json"
"github.com/rocket-pool/node-manager-core/utils"
)

// Request types
type VoluntaryExitMessage struct {
Epoch Uinteger `json:"epoch"`
ValidatorIndex string `json:"validator_index"`
Epoch utils.Uinteger `json:"epoch"`
ValidatorIndex string `json:"validator_index"`
}
type VoluntaryExitRequest struct {
Message VoluntaryExitMessage `json:"message"`
Signature ByteArray `json:"signature"`
Signature utils.ByteArray `json:"signature"`
}
type BLSToExecutionChangeMessage struct {
ValidatorIndex string `json:"validator_index"`
FromBLSPubkey ByteArray `json:"from_bls_pubkey"`
ToExecutionAddress ByteArray `json:"to_execution_address"`
ValidatorIndex string `json:"validator_index"`
FromBLSPubkey utils.ByteArray `json:"from_bls_pubkey"`
ToExecutionAddress utils.ByteArray `json:"to_execution_address"`
}
type BLSToExecutionChangeRequest struct {
Message BLSToExecutionChangeMessage `json:"message"`
Signature ByteArray `json:"signature"`
Signature utils.ByteArray `json:"signature"`
}

// Response types
type SyncStatusResponse struct {
Data struct {
IsSyncing bool `json:"is_syncing"`
HeadSlot Uinteger `json:"head_slot"`
SyncDistance Uinteger `json:"sync_distance"`
IsSyncing bool `json:"is_syncing"`
HeadSlot utils.Uinteger `json:"head_slot"`
SyncDistance utils.Uinteger `json:"sync_distance"`
} `json:"data"`
}
type Eth2ConfigResponse struct {
Data struct {
SecondsPerSlot Uinteger `json:"SECONDS_PER_SLOT"`
SlotsPerEpoch Uinteger `json:"SLOTS_PER_EPOCH"`
EpochsPerSyncCommitteePeriod Uinteger `json:"EPOCHS_PER_SYNC_COMMITTEE_PERIOD"`
CapellaForkVersion ByteArray `json:"CAPELLA_FORK_VERSION"`
SecondsPerSlot utils.Uinteger `json:"SECONDS_PER_SLOT"`
SlotsPerEpoch utils.Uinteger `json:"SLOTS_PER_EPOCH"`
EpochsPerSyncCommitteePeriod utils.Uinteger `json:"EPOCHS_PER_SYNC_COMMITTEE_PERIOD"`
CapellaForkVersion utils.ByteArray `json:"CAPELLA_FORK_VERSION"`
} `json:"data"`
}
type Eth2DepositContractResponse struct {
Data struct {
ChainID Uinteger `json:"chain_id"`
ChainID utils.Uinteger `json:"chain_id"`
Address common.Address `json:"address"`
} `json:"data"`
}
type GenesisResponse struct {
Data struct {
GenesisTime Uinteger `json:"genesis_time"`
GenesisForkVersion ByteArray `json:"genesis_fork_version"`
GenesisValidatorsRoot ByteArray `json:"genesis_validators_root"`
GenesisTime utils.Uinteger `json:"genesis_time"`
GenesisForkVersion utils.ByteArray `json:"genesis_fork_version"`
GenesisValidatorsRoot utils.ByteArray `json:"genesis_validators_root"`
} `json:"data"`
}
type FinalityCheckpointsResponse struct {
Data struct {
PreviousJustified struct {
Epoch Uinteger `json:"epoch"`
Epoch utils.Uinteger `json:"epoch"`
} `json:"previous_justified"`
CurrentJustified struct {
Epoch Uinteger `json:"epoch"`
Epoch utils.Uinteger `json:"epoch"`
} `json:"current_justified"`
Finalized struct {
Epoch Uinteger `json:"epoch"`
Epoch utils.Uinteger `json:"epoch"`
} `json:"finalized"`
} `json:"data"`
}
type ForkResponse struct {
Data struct {
PreviousVersion ByteArray `json:"previous_version"`
CurrentVersion ByteArray `json:"current_version"`
Epoch Uinteger `json:"epoch"`
PreviousVersion utils.ByteArray `json:"previous_version"`
CurrentVersion utils.ByteArray `json:"current_version"`
Epoch utils.Uinteger `json:"epoch"`
} `json:"data"`
}
type AttestationsResponse struct {
Expand All @@ -82,18 +79,18 @@ type AttestationsResponse struct {
type BeaconBlockResponse struct {
Data struct {
Message struct {
Slot Uinteger `json:"slot"`
ProposerIndex string `json:"proposer_index"`
Slot utils.Uinteger `json:"slot"`
ProposerIndex string `json:"proposer_index"`
Body struct {
Eth1Data struct {
DepositRoot ByteArray `json:"deposit_root"`
DepositCount Uinteger `json:"deposit_count"`
BlockHash ByteArray `json:"block_hash"`
DepositRoot utils.ByteArray `json:"deposit_root"`
DepositCount utils.Uinteger `json:"deposit_count"`
BlockHash utils.ByteArray `json:"block_hash"`
} `json:"eth1_data"`
Attestations []Attestation `json:"attestations"`
ExecutionPayload *struct {
FeeRecipient ByteArray `json:"fee_recipient"`
BlockNumber Uinteger `json:"block_number"`
FeeRecipient utils.ByteArray `json:"fee_recipient"`
BlockNumber utils.Uinteger `json:"block_number"`
} `json:"execution_payload"`
} `json:"body"`
} `json:"message"`
Expand All @@ -106,8 +103,8 @@ type BeaconBlockHeaderResponse struct {
Canonical bool `json:"canonical"`
Header struct {
Message struct {
Slot Uinteger `json:"slot"`
ProposerIndex string `json:"proposer_index"`
Slot utils.Uinteger `json:"slot"`
ProposerIndex string `json:"proposer_index"`
} `json:"message"`
} `json:"header"`
} `json:"data"`
Expand All @@ -116,27 +113,27 @@ type ValidatorsResponse struct {
Data []Validator `json:"data"`
}
type Validator struct {
Index string `json:"index"`
Balance Uinteger `json:"balance"`
Status string `json:"status"`
Index string `json:"index"`
Balance utils.Uinteger `json:"balance"`
Status string `json:"status"`
Validator struct {
Pubkey ByteArray `json:"pubkey"`
WithdrawalCredentials ByteArray `json:"withdrawal_credentials"`
EffectiveBalance Uinteger `json:"effective_balance"`
Slashed bool `json:"slashed"`
ActivationEligibilityEpoch Uinteger `json:"activation_eligibility_epoch"`
ActivationEpoch Uinteger `json:"activation_epoch"`
ExitEpoch Uinteger `json:"exit_epoch"`
WithdrawableEpoch Uinteger `json:"withdrawable_epoch"`
Pubkey utils.ByteArray `json:"pubkey"`
WithdrawalCredentials utils.ByteArray `json:"withdrawal_credentials"`
EffectiveBalance utils.Uinteger `json:"effective_balance"`
Slashed bool `json:"slashed"`
ActivationEligibilityEpoch utils.Uinteger `json:"activation_eligibility_epoch"`
ActivationEpoch utils.Uinteger `json:"activation_epoch"`
ExitEpoch utils.Uinteger `json:"exit_epoch"`
WithdrawableEpoch utils.Uinteger `json:"withdrawable_epoch"`
} `json:"validator"`
}
type SyncDutiesResponse struct {
Data []SyncDuty `json:"data"`
}
type SyncDuty struct {
Pubkey ByteArray `json:"pubkey"`
ValidatorIndex string `json:"validator_index"`
SyncCommitteeIndices []Uinteger `json:"validator_sync_committee_indices"`
Pubkey utils.ByteArray `json:"pubkey"`
ValidatorIndex string `json:"validator_index"`
SyncCommitteeIndices []utils.Uinteger `json:"validator_sync_committee_indices"`
}
type ProposerDutiesResponse struct {
Data []ProposerDuty `json:"data"`
Expand All @@ -152,59 +149,7 @@ type CommitteesResponse struct {
type Attestation struct {
AggregationBits string `json:"aggregation_bits"`
Data struct {
Slot Uinteger `json:"slot"`
Index Uinteger `json:"index"`
Slot utils.Uinteger `json:"slot"`
Index utils.Uinteger `json:"index"`
} `json:"data"`
}

// Unsigned integer type
type Uinteger uint64

func (i Uinteger) MarshalJSON() ([]byte, error) {
return json.Marshal(strconv.FormatUint(uint64(i), 10))
}
func (i *Uinteger) UnmarshalJSON(data []byte) error {

// Unmarshal string
var dataStr string
if err := json.Unmarshal(data, &dataStr); err != nil {
return err
}

// Parse integer value
value, err := strconv.ParseUint(dataStr, 10, 64)
if err != nil {
return err
}

// Set value and return
*i = Uinteger(value)
return nil

}

// Byte array type
type ByteArray []byte

func (b ByteArray) MarshalJSON() ([]byte, error) {
return json.Marshal(utils.EncodeHexWithPrefix(b))
}
func (b *ByteArray) UnmarshalJSON(data []byte) error {

// Unmarshal string
var dataStr string
if err := json.Unmarshal(data, &dataStr); err != nil {
return err
}

// Decode hex
value, err := utils.DecodeHex(dataStr)
if err != nil {
return err
}

// Set value and return
*b = value
return nil

}
6 changes: 2 additions & 4 deletions config/besu-config.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ import (
// Constants
const (
// Tags
besuTagTest string = "hyperledger/besu:24.6.0"
besuTagProd string = "hyperledger/besu:24.6.0"
besuTag string = "hyperledger/besu:24.7.0"
)

// Configuration for Besu
Expand Down Expand Up @@ -101,8 +100,7 @@ func NewBesuConfig() *BesuConfig {
OverwriteOnUpgrade: true,
},
Default: map[Network]string{
Network_Mainnet: besuTagProd,
Network_Holesky: besuTagTest,
Network_All: besuTag,
},
},

Expand Down
39 changes: 39 additions & 0 deletions config/cfg-section.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,42 @@ func ApplyDefaults(cfg IConfigSection, network Network) {
ApplyDefaults(subconfig, network)
}
}

// Assign the default values of a config section for the provided network
func SetDefaultsForNetworks(cfg IConfigSection, defaults map[string]any, network Network) error {
// Handle the parameters
params := cfg.GetParameters()
for _, param := range params {
id := param.GetCommon().ID
val, exists := defaults[id]
if !exists {
continue
}
valString, isString := val.(string)
if !isString {
return fmt.Errorf("parameter [%s] is not a string but has a parameter ID name", id)
}
err := param.SetDefaultValueForNetwork(valString, network)
if err != nil {
return err
}
}

// Handle the subconfigs
subconfigs := cfg.GetSubconfigs()
for name, subconfig := range subconfigs {
subParams, exists := defaults[name]
if exists {
submap, isMap := subParams.(map[string]any)
if !isMap {
return fmt.Errorf("subsection [%s] is not a map, it is %s", name, reflect.TypeOf(subParams))
}
err := SetDefaultsForNetworks(subconfig, submap, network)
if err != nil {
return fmt.Errorf("error deserializing subsection [%s]: %w", name, err)
}
}
}

return nil
}
Loading
Loading