Skip to content

Commit

Permalink
uallo values to get over uint64 (eg minStake) (#107)
Browse files Browse the repository at this point in the history
<!-- < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < ☺
v           ✰  Thanks for creating a PR! You're awesome! ✰
v Please note that maintainers will only review those PRs with a
completed PR template.
☺ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > >  -->

## Purpose of Changes and their Description
Fix to use `cosmosSdk.Int` (ie `big.Int`) on uallo amounts. 
This allows reputers to stake higher amounts than those covered by
`uint64`.
Config changes type since this needs to specify such amounts as `string`
in the json.

## Are these changes tested and documented?

- [x] If tested, please describe how. If not, why tests are not needed.
-- Tested locally
- [x] If documented, please describe where. If not, describe why docs
are not needed. -- Modified README accordingly
- [x] Added to `Unreleased` section of `CHANGELOG.md`?
  • Loading branch information
xmariachi authored Jan 16, 2025
1 parent 5268a92 commit 23c2cad
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 36 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Security


## [Unreleased]
## v0.8.1

### Added

Expand All @@ -69,6 +69,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Fixed

* [#107](https://github.com/allora-network/allora-offchain-node/pull/107) uallo values to get over uint64 (eg minStake)

### Removed

### Fixed
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ These below are excerpts of the configuration (with some parts omitted for brevi
"topicId": 1,
"groundTruthEntrypointName": "apiAdapter",
"lossFunctionEntrypointName": "apiAdapter",
"minStake": 100000,
"minStake": "100000000",
"groundTruthParameters": {
"GroundTruthEndpoint": "http://localhost:8888/gt/{Token}/{BlockHeight}",
"Token": "ETHUSD"
Expand Down Expand Up @@ -281,7 +281,7 @@ These below are excerpts of the configuration (with some parts omitted for brevi
"topicId": 1,
"groundTruthEntrypointName": "apiAdapter",
"lossFunctionEntrypointName": "apiAdapter",
"minStake": 100000,
"minStake": "100000000",
"groundTruthParameters": {
"GroundTruthEndpoint": "http://localhost:8888/gt/{Token}/{BlockHeight}",
"Token": "ETHUSD"
Expand Down
4 changes: 2 additions & 2 deletions config.example.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"gasAdjustment": 1.2,
"gasPrices": "auto",
"gasPriceUpdateInterval": 60,
"maxFees": 500000,
"maxFees": "500000",
"nodeRpc": "https://allora-rpc.testnet.allora.network",
"maxRetries": 5,
"retryDelay": 3,
Expand Down Expand Up @@ -35,7 +35,7 @@
"topicId": 1,
"groundTruthEntrypointName": "apiAdapter",
"lossFunctionEntrypointName": "apiAdapter",
"minStake": 100000,
"minStake": "100000000",
"groundTruthParameters": {
"GroundTruthEndpoint": "http://localhost:8888/gt/{Token}/{BlockHeight}",
"Token": "ETHUSD"
Expand Down
36 changes: 18 additions & 18 deletions lib/domain_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,23 +36,23 @@ type WalletConfig struct {
Address string // will be overwritten by the keystore. This is the 1 value that is auto-generated in this struct
AddressKeyName string // load a address by key from the keystore
AddressRestoreMnemonic string
AlloraHomeDir string // home directory for the allora keystore
Gas string // gas to use for the allora client
GasAdjustment float64 // gas adjustment to use for the allora client
GasPrices string // gas prices to use for the allora client - "auto" for auto-calculated fees
GasPriceUpdateInterval int64 // number of seconds to wait between updates to the gas price
MaxFees uint64 // max fees to pay for a single transaction
NodeRpc string // rpc node for allora chain
MaxRetries int64 // retry to get data from chain up to this many times per query or tx
RetryDelay int64 // number of seconds to wait between retries (general case)
AccountSequenceRetryDelay int64 // number of seconds to wait between retries in case of account sequence error
SubmitTx bool // useful for dev/testing. set to false to run in dry-run processes without committing to the chain
BlockDurationEstimated float64 // estimated average block duration in seconds
WindowCorrectionFactor float64 // correction factor for the time estimation, suggested range 0.7-0.9.
TimeoutRPCSecondsQuery int64 // timeout for rpc queries in seconds, including retries
TimeoutRPCSecondsTx int64 // timeout for rpc data send in seconds, including retries
TimeoutRPCSecondsRegistration int64 // timeout for rpc registration in seconds, including retries
TimeoutHTTPConnection int64 // timeout for http connection in seconds
AlloraHomeDir string // home directory for the allora keystore
Gas string // gas to use for the allora client
GasAdjustment float64 // gas adjustment to use for the allora client
GasPrices string // gas prices to use for the allora client - "auto" for auto-calculated fees
GasPriceUpdateInterval int64 // number of seconds to wait between updates to the gas price
MaxFees FlexibleCosmosIntAmount // max fees to pay for a single transaction (as string or number)
NodeRpc string // rpc node for allora chain
MaxRetries int64 // retry to get data from chain up to this many times per query or tx
RetryDelay int64 // number of seconds to wait between retries (general case)
AccountSequenceRetryDelay int64 // number of seconds to wait between retries in case of account sequence error
SubmitTx bool // useful for dev/testing. set to false to run in dry-run processes without committing to the chain
BlockDurationEstimated float64 // estimated average block duration in seconds
WindowCorrectionFactor float64 // correction factor for the time estimation, suggested range 0.7-0.9.
TimeoutRPCSecondsQuery int64 // timeout for rpc queries in seconds, including retries
TimeoutRPCSecondsTx int64 // timeout for rpc data send in seconds, including retries
TimeoutRPCSecondsRegistration int64 // timeout for rpc registration in seconds, including retries
TimeoutHTTPConnection int64 // timeout for http connection in seconds
}

// Properties auto-generated based on what the user has provided in WalletConfig fields of UserConfig
Expand Down Expand Up @@ -95,7 +95,7 @@ type ReputerConfig struct {
// Will not repute if current stake is less than this, after trying to add any necessary stake.
// This is idempotent in that it will not add more stake than specified here.
// Set to 0 to effectively disable this feature and use whatever stake has already been added.
MinStake int64
MinStake FlexibleCosmosIntAmount
GroundTruthParameters map[string]string // Map for variable configuration values
LossFunctionParameters LossFunctionParameters // Map for variable configuration values
}
Expand Down
16 changes: 11 additions & 5 deletions lib/repo_tx_registration.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@ import (
"context"
"fmt"

"github.com/rs/zerolog/log"

cosmossdk_io_math "cosmossdk.io/math"
emissionstypes "github.com/allora-network/allora-chain/x/emissions/types"
"github.com/rs/zerolog/log"
)

// True if the actor is ultimately, definitively registered for the specified topic, else False
Expand Down Expand Up @@ -149,9 +147,17 @@ func (node *NodeConfig) RegisterAndStakeReputerIdempotently(ctx context.Context,
return false, err
}

minStake := cosmossdk_io_math.NewInt(config.MinStake)
minStake := config.MinStake.Number
if minStake.IsNil() {
log.Info().Msg("No minimum stake configured in reputer, skipping adding stake.")
return true, nil
}
if minStake.IsZero() {
log.Info().Msg("No minimum stake requested, skipping adding stake.")
return true, nil
}
if minStake.LTE(stake) {
log.Info().Msg("Stake above minimum requested stake, skipping adding stake.")
log.Info().Interface("stake", stake).Interface("minStake", minStake).Msg("Stake above minimum requested stake, skipping adding stake.")
return true, nil
} else {
log.Info().Interface("stake", stake).Interface("minStake", minStake).Interface("stakeToAdd", minStake.Sub(stake)).Msg("Stake below minimum requested stake, adding stake.")
Expand Down
19 changes: 11 additions & 8 deletions lib/repo_tx_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ import (
"strconv"
"strings"

"github.com/rs/zerolog/log"

errorsmod "cosmossdk.io/errors"
cosmossdk_io_math "cosmossdk.io/math"
emissions "github.com/allora-network/allora-chain/x/emissions/types"
sdktypes "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/ignite/cli/v28/ignite/pkg/cosmosclient"
"github.com/rs/zerolog/log"
feemarkettypes "github.com/skip-mev/feemarket/x/feemarket/types"
)

Expand Down Expand Up @@ -249,18 +249,21 @@ func (node *NodeConfig) SendDataWithRetry(ctx context.Context, req sdktypes.Msg,

// Handle fees if necessary
if gasPrices > 0 {

// Precalculate fees
estimatedGas := float64(txService.Gas()) * node.Wallet.GasAdjustment
fees := uint64(float64(estimatedGas+EXCESS_CORRECTION_IN_GAS) * gasPrices)
feesFloat := float64(estimatedGas+EXCESS_CORRECTION_IN_GAS) * gasPrices
fees := cosmossdk_io_math.NewInt(int64(feesFloat))
// Add excess fees correction factor to increase with each fee-problematic retry
fees = fees + uint64(float64(recalculateFees)*excessFactorFees)
feeAdjustment := int64(float64(recalculateFees) * excessFactorFees)
fees = fees.Add(cosmossdk_io_math.NewInt(feeAdjustment))
// Limit fees to maxFees
if fees > node.Wallet.MaxFees {
log.Warn().Uint64("gas", txService.Gas()).Uint64("limit", node.Wallet.MaxFees).Msg("Gas limit exceeded, using maxFees instead")
fees = node.Wallet.MaxFees
if fees.GT(node.Wallet.MaxFees.Number) {
log.Warn().Uint64("gas", txService.Gas()).Interface("limit", node.Wallet.MaxFees).Msg("Gas limit exceeded, using maxFees instead")
fees = node.Wallet.MaxFees.Number
}
txOptions := cosmosclient.TxOptions{ // nolint: exhaustruct
Fees: fmt.Sprintf("%duallo", fees),
Fees: fmt.Sprintf("%suallo", fees.String()),
}
log.Info().Str("fees", txOptions.Fees).Msg("Attempting tx with calculated fees")
txService, err = node.Chain.Client.CreateTxWithOptions(ctx, node.Chain.Account, txOptions, req)
Expand Down
46 changes: 46 additions & 0 deletions lib/type_allora.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,51 @@
package lib

import (
"encoding/json"
"fmt"
"strconv"

cosmossdk_io_math "cosmossdk.io/math"
)

type Address = string
type Allo = int64
type BlockHeight = int64

// FlexibleCosmosIntAmount represents amounts of tokens, where the amount can be specified or as a string
type FlexibleCosmosIntAmount struct {
Number cosmossdk_io_math.Int
}

func (fv *FlexibleCosmosIntAmount) String() string {
return fv.Number.String()
}

func (fv *FlexibleCosmosIntAmount) UnmarshalJSON(data []byte) error {
// Handle number
if data[0] >= '0' && data[0] <= '9' {
var num json.Number
if err := json.Unmarshal(data, &num); err != nil {
return fmt.Errorf("failed to parse number: %w", err)
}
cosmosInt, ok := cosmossdk_io_math.NewIntFromString(num.String())
if !ok {
return fmt.Errorf("failed to convert number to cosmosInt: %s", num.String())
}
fv.Number = cosmosInt
return nil
}

// Handle string
var str string
if err := json.Unmarshal(data, &str); err == nil {
num, err := strconv.ParseInt(str, 10, 64)
if err != nil {
return fmt.Errorf("failed to convert string to number: %w", err)
}
fv.Number = cosmossdk_io_math.NewInt(num)
return nil
}

return fmt.Errorf("invalid value: %s", string(data))
}

0 comments on commit 23c2cad

Please sign in to comment.