Skip to content
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
34 changes: 30 additions & 4 deletions shared/services/gas/etherscan/etherscan.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,16 @@ import (
"strconv"
)

const gasOracleUrl string = "https://api.etherscan.io/api?module=gastracker&action=gasoracle"
const gasOracleUrl string = "https://api.etherscan.io/v2/api?module=gastracker&action=gasoracle&chainId=1"

// Standard response
type gasOracleResponse struct {
Status uinteger `json:"status"`
Message string `json:"message"`
Result struct {
SafeGasPrice uinteger `json:"SafeGasPrice"`
ProposeGasPrice uinteger `json:"ProposeGasPrice"`
FastGasPrice uinteger `json:"FastGasPrice"`
SafeGasPrice gasfloat `json:"SafeGasPrice"`
ProposeGasPrice gasfloat `json:"ProposeGasPrice"`
FastGasPrice gasfloat `json:"FastGasPrice"`
} `json:"result"`
}

Expand Down Expand Up @@ -115,3 +115,29 @@ func (i *uinteger) UnmarshalJSON(data []byte) error {
*i = uinteger(value)
return nil
}

// Float type for gas prices (v2 API returns fractional gwei values like "0.13866663")
type gasfloat float64

func (f gasfloat) MarshalJSON() ([]byte, error) {
return json.Marshal(strconv.FormatFloat(float64(f), 'f', -1, 64))
}

func (f *gasfloat) UnmarshalJSON(data []byte) error {

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

// Parse float value
value, err := strconv.ParseFloat(dataStr, 64)
if err != nil {
return err
}

// Set value and return
*f = gasfloat(value)
return nil
}
45 changes: 16 additions & 29 deletions shared/services/gas/gas.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import (

"github.com/stader-labs/stader-node/shared/utils/log"

"github.com/stader-labs/stader-node/shared/services/gas/etherchain"
"github.com/stader-labs/stader-node/shared/services/gas/etherscan"
"github.com/stader-labs/stader-node/shared/services/stader"
cliutils "github.com/stader-labs/stader-node/shared/utils/cli"
Expand Down Expand Up @@ -90,22 +89,16 @@ func AssignMaxFeeAndLimit(gasInfo staderCore.GasInfo, staderClient *stader.Clien
}
maxFeeGwei = eth.WeiToGwei(maxFeeWei)
} else {
// Try to get the latest gas prices from Etherchain
etherchainData, err := etherchain.GetGasPrices()
// Try to get the latest gas prices from Etherscan
etherscanData, err := etherscan.GetGasPrices()
if err == nil {
// Print the Etherchain data and ask for an amount
maxFeeGwei = handleEtherchainGasPrices(etherchainData, maxPriorityFeeGwei)

// Print the Etherscan data and ask for an amount
maxFeeGwei = handleEtherscanGasPrices(etherscanData, maxPriorityFeeGwei)
} else {
// Fallback to Etherscan
fmt.Printf("%sWarning: couldn't get gas estimates from Etherchain - %s\nFalling back to Etherscan%s\n", log.ColorYellow, err.Error(), log.ColorReset)
etherscanData, err := etherscan.GetGasPrices()
if err == nil {
// Print the Etherscan data and ask for an amount
maxFeeGwei = handleEtherscanGasPrices(etherscanData, maxPriorityFeeGwei)
} else {
return fmt.Errorf("Error getting gas price suggestions: %w", err)
}
// Fallback to manual entry
fmt.Printf("%sWarning: couldn't get gas estimates from Etherscan - %s\n", log.ColorYellow, err.Error())
fmt.Printf("This may be due to Etherscan's free API rate limit (1 request per 5 seconds). Please try again in a few seconds or enter a max fee manually.%s\n", log.ColorReset)
maxFeeGwei = handleManualGasEntry(maxPriorityFeeGwei)
}
}
fmt.Printf("%sUsing a max fee of %.2f gwei and a priority fee of %.2f gwei.\n%s", log.ColorBlue, maxFeeGwei, maxPriorityFeeGwei, log.ColorReset)
Expand All @@ -126,12 +119,6 @@ func AssignMaxFeeAndLimit(gasInfo staderCore.GasInfo, staderClient *stader.Clien

// Get the suggested max fee for service operations
func GetHeadlessMaxFeeWei() (*big.Int, error) {
etherchainData, err := etherchain.GetGasPrices()
if err == nil {
return etherchainData.RapidWei, nil
}

fmt.Printf("%sWarning: couldn't get gas estimates from Etherchain - %s\nFalling back to Etherscan%s\n", log.ColorYellow, err.Error(), log.ColorReset)
etherscanData, err := etherscan.GetGasPrices()
if err == nil {
return eth.GweiToWei(etherscanData.FastGwei), nil
Expand All @@ -140,8 +127,9 @@ func GetHeadlessMaxFeeWei() (*big.Int, error) {
return nil, fmt.Errorf("Error getting gas price suggestions: %w", err)
}

func handleEtherchainGasPrices(gasSuggestion etherchain.GasFeeSuggestion, priorityFee float64) float64 {
fastGwei := math.RoundUp(eth.WeiToGwei(gasSuggestion.FastWei)+priorityFee, 0)
func handleEtherscanGasPrices(gasSuggestion etherscan.GasFeeSuggestion, priorityFee float64) float64 {

fastGwei := math.RoundUp(gasSuggestion.FastGwei+priorityFee, 0)

for {
desiredPrice := cliutils.Prompt(
Expand All @@ -155,7 +143,7 @@ func handleEtherchainGasPrices(gasSuggestion etherchain.GasFeeSuggestion, priori

desiredPriceFloat, err := strconv.ParseFloat(desiredPrice, 64)
if err != nil {
fmt.Printf("Not a valid gas price (%s), try again.", err.Error())
fmt.Printf("Not a valid gas price (%s), try again.\n", err.Error())
continue
}
if desiredPriceFloat <= 0 {
Expand All @@ -168,18 +156,17 @@ func handleEtherchainGasPrices(gasSuggestion etherchain.GasFeeSuggestion, priori

}

func handleEtherscanGasPrices(gasSuggestion etherscan.GasFeeSuggestion, priorityFee float64) float64 {

fastGwei := math.RoundUp(gasSuggestion.FastGwei+priorityFee, 0)
func handleManualGasEntry(priorityFee float64) float64 {

for {
desiredPrice := cliutils.Prompt(
fmt.Sprintf("Please enter your max fee (including the priority fee) or leave blank for the default of %d gwei:", int(fastGwei)),
"Please enter your max fee (including the priority fee) in gwei (e.g. 2):",
"^(?:[1-9]\\d*|0)?(?:\\.\\d+)?$",
"Not a valid gas price, try again:")

if desiredPrice == "" {
return fastGwei
fmt.Println("Max fee is required, please enter a value.")
continue
}

desiredPriceFloat, err := strconv.ParseFloat(desiredPrice, 64)
Expand Down
2 changes: 1 addition & 1 deletion shared/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ package shared

const BinaryBucket string = "/stader-node-build/permissionless"
const DockerAccount string = "staderlabs"
const StaderVersion string = "1.7.2"
const StaderVersion string = "1.7.3"

const Logo string = `
_____ _ _ _ _ 𝅺
Expand Down
10 changes: 10 additions & 0 deletions stader-cli/service/migration.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@ func migrate(c *cli.Context) (runBeforeUpgrades, rundAfterUpgrades []ConfigUpgra
return nil, nil, err
}

v173, err := parseVersion("1.7.3")
if err != nil {
return nil, nil, err
}

// Create the collection of upgraders
upgraders := []ConfigUpgrader{
{
Expand Down Expand Up @@ -160,6 +165,11 @@ func migrate(c *cli.Context) (runBeforeUpgrades, rundAfterUpgrades []ConfigUpgra
upgradeFunc: func(_ *cli.Context) error { return nil },
needInstall: true,
},
{
version: v173,
upgradeFunc: func(_ *cli.Context) error { return nil },
needInstall: true,
},
}

staderClient, err := stader.NewClientFromCtx(c)
Expand Down
Loading