Skip to content

feat: tune default min gas price - #41

Merged
safrochain merged 9 commits into
Safrochain-Org:mainfrom
danbaruka:main
May 25, 2026
Merged

safrochain merged 9 commits into
Safrochain-Org:mainfrom
danbaruka:main

Conversation

@danbaruka

Copy link
Copy Markdown
Member

Summary

Drops the default --minimum-gas-prices from 100000usaf (set in #25) to 0.05usaf so that day-one transaction fees on Safrochain stay in the cent range instead of costing several thousand SAF per send.

Why this is needed

The current default of 100000usaf per gas unit was off by roughly 6 orders of magnitude. A standard MsgSend at the typical ~80 000 gas would cost:

80 000 gas × 100 000 usaf/gas = 8 000 000 000 usaf = 8 000 SAF

That is more than any community validator's self-stake. In practice it would either:

  • block all economic activity on the chain, or
  • force every operator to override the default in app.toml, which silently splinters the fee market.

The default needs to be a sane floor that operators could override upward, not a number they must override downward.

Proposed value: 0.05usaf per gas

Calibrated against typical Cosmos SDK gas costs:

Operation Typical gas Fee at 0.05 usaf/gas Human-readable
MsgSend 80 000 4 000 usaf ~0.004 SAF
MsgDelegate 200 000 10 000 usaf ~0.010 SAF
IBC MsgTransfer 200 000 10 000 usaf ~0.010 SAF
CosmWasm contract call 1 000 000 50 000 usaf ~0.050 SAF

This keeps fees in the single-cent range for end users while still producing meaningful validator fee revenue (roughly 10× higher per-tx than the 0.005usaf value I evaluated earlier).

Why not 0?

A non-zero default protects the chain from trivial spam at the mempool layer before governance has the chance to set a globalfee floor. 0.05usaf is small enough not to harm users and large enough that flooding the chain costs real value.

Why this is the right place to set it

DefaultMinGasPrices in cmd/safrochaind/cmd/root.go is the value that gets written into a fresh app.toml on safrochaind init. Operators can still override via app.toml minimum-gas-prices or the --minimum-gas-prices CLI flag — this change only sets the sane default for new installs.

Changes

  • cmd/safrochaind/cmd/root.go: DefaultMinGasPrices "100000usaf" → "0.05usaf" (1 line)

Out of scope

  • On-chain x/globalfee minimum (governed by params, not this default).
  • Validator-level overrides via existing app.toml. Existing validators are unaffected; only freshly initialised nodes pick up the new default.

Test plan

  • make install and confirm safrochaind init writes minimum-gas-prices = "0.05usaf" in ~/.safrochain/config/app.toml
  • Start a single-node devnet and submit a MsgSend with --fees 4000usaf — accepts.
  • Submit the same MsgSend with --fees 100usaf — rejected with "insufficient fees".
  • Existing nodes upgrading do not see their app.toml overwritten (default is only applied on init).

Release notes

Lowered the default minimum-gas-prices from 100000usaf to 0.05usaf. Existing nodes are unaffected; new safrochaind init runs will pick up the lower default. Operators who want a higher floor can still override in app.toml.

* Remove the Safrochain Validator Setup and Maintenance Guide document, streamlining project resources.

* feat: add SECURITY.md security policy
* Remove the Safrochain Validator Setup and Maintenance Guide document, streamlining project resources.

* feat: add --mainnet flag to switch Bech32 address prefix at runtime

Introduces a persistent --mainnet CLI flag that selects the correct
Bech32 address prefix before sdk.GetConfig().Seal() is called:

- Default (testnet): addr_safro / addr_safrovaloper / addr_safrovalcons
- --mainnet:         safro      / safrovaloper      / safrovalcons

os.Args is pre-scanned via getBech32Prefix() so the prefix is set
before Cobra parses flags, which is required by the Cosmos SDK config
seal contract.


* revert(cli): use single Bech32 prefix addr_safro for all networks

Remove --mainnet flag and runtime prefix switching; align with standard
Cosmos practice (chain-id distinguishes networks, not HRP).


* refactor: update fee handling and address prefix consistency

- Refactored fee handling in ante decorators to eliminate shared state, using per-transaction context for FeePay routing (SAF-08).
- Updated gas limit parameters for clock module to improve contract execution limits.
- Standardized Bech32 address prefix to 'addr_safro' across all modules, ensuring consistency in address validation.
- Enhanced error handling in governance hooks to log contract execution failures.
- Implemented stricter validation for the Drip module, requiring non-empty allow-lists for enabled states (SAF-06).
- Adjusted test cases to reflect new address prefix and gas limit changes, ensuring compatibility with updated logic.

---------
…(PR #14)

Bumps direct and transitive dependencies in both go.mod and
interchaintest/go.mod to versions that fix the open Dependabot
advisories surfaced on Safrochain-Org/safrochain-node.

Direct upgrades (root + interchaintest):
- github.com/cosmos/cosmos-sdk         v0.50.13 -> v0.50.14
- github.com/CosmWasm/wasmd            v0.54.0  -> v0.54.1
- github.com/cometbft/cometbft         v0.38.17 -> v0.38.21
- google.golang.org/grpc               v1.72.0  -> v1.79.3
- github.com/docker/docker (e2e only)  v24.0.9  -> v25.0.14

Transitive minimum-version upgrades:
- filippo.io/edwards25519              v1.1.0   -> v1.1.1
- github.com/go-jose/go-jose/v4        v4.0.4   -> v4.1.4
- github.com/hashicorp/go-getter       v1.7.5   -> v1.8.6
- github.com/go-viper/mapstructure/v2  v2.2.1   -> v2.4.0
- github.com/ulikunitz/xz              v0.5.11  -> v0.5.15
- go.opentelemetry.io/otel*            v1.34.0  -> v1.43.0
- golang.org/x/crypto                  v0.37.0  -> v0.49.0
- golang.org/x/oauth2                  v0.26.0  -> v0.36.0
- github.com/shamaton/msgpack/v2       v2.2.0   -> v2.4.0

interchaintest-only (e2e):
- github.com/ethereum/go-ethereum      v1.14.8  -> v1.17.2
- github.com/cosmos/interchain-security/v5 v5.1.1 -> v5.2.0
- github.com/consensys/gnark-crypto    v0.12.1  -> v0.18.2

Other:
- github.com/bytedance/sonic           v1.13.2  -> v1.15.0
  (required by Go 1.25 linkname rules)
- enable the local replace
  github.com/Safrochain_Org/safrochain => ../ in interchaintest/go.mod
  (the prior commented placeholder pointed at a non-existent v1.0.0 tag)

Toolchain:
- go directive bumped from 1.23.9 to 1.25.8 in both go.mod files
  because several upgraded transitive dependencies now require Go 1.25.
- CI workflows, Dockerfile, build_release.sh and .mise.toml updated
  to match.

Alerts not addressed in this PR:
- github.com/btcsuite/btcd (3 alerts): the patched 0.23.2+ releases
  remove the legacy btcec package that github.com/tendermint/tendermint
  v0.38.0-dev (pulled in transitively by interchaintest's namada chain
  support) still imports. Bumping breaks that build path.
- github.com/docker/docker (2 alerts): the advisories request 29.3.1,
  which has not yet been published as a Go module. Bumped to v25.0.14
  to close the two alerts that have available patches.
- github.com/shamaton/msgpack/v2: no patched release yet; bumped to
  the latest available (v2.4.0).
* Remove the Safrochain Validator Setup and Maintenance Guide document, streamlining project resources.

* feat: add --mainnet flag to switch Bech32 address prefix at runtime

Introduces a persistent --mainnet CLI flag that selects the correct
Bech32 address prefix before sdk.GetConfig().Seal() is called:

- Default (testnet): addr_safro / addr_safrovaloper / addr_safrovalcons
- --mainnet:         safro      / safrovaloper      / safrovalcons

os.Args is pre-scanned via getBech32Prefix() so the prefix is set
before Cobra parses flags, which is required by the Cosmos SDK config
seal contract.

* revert(cli): use single Bech32 prefix addr_safro for all networks

Remove --mainnet flag and runtime prefix switching; align with standard
Cosmos practice (chain-id distinguishes networks, not HRP).

* security: bulk-resolve Dependabot alerts via dependency upgrades

Bumps direct and transitive dependencies in both go.mod and
interchaintest/go.mod to versions that fix the open Dependabot
advisories surfaced on Safrochain-Org/safrochain-node.

Direct upgrades (root + interchaintest):
- github.com/cosmos/cosmos-sdk         v0.50.13 -> v0.50.14
- github.com/CosmWasm/wasmd            v0.54.0  -> v0.54.1
- github.com/cometbft/cometbft         v0.38.17 -> v0.38.21
- google.golang.org/grpc               v1.72.0  -> v1.79.3
- github.com/docker/docker (e2e only)  v24.0.9  -> v25.0.14

Transitive minimum-version upgrades:
- filippo.io/edwards25519              v1.1.0   -> v1.1.1
- github.com/go-jose/go-jose/v4        v4.0.4   -> v4.1.4
- github.com/hashicorp/go-getter       v1.7.5   -> v1.8.6
- github.com/go-viper/mapstructure/v2  v2.2.1   -> v2.4.0
- github.com/ulikunitz/xz              v0.5.11  -> v0.5.15
- go.opentelemetry.io/otel*            v1.34.0  -> v1.43.0
- golang.org/x/crypto                  v0.37.0  -> v0.49.0
- golang.org/x/oauth2                  v0.26.0  -> v0.36.0
- github.com/shamaton/msgpack/v2       v2.2.0   -> v2.4.0

interchaintest-only (e2e):
- github.com/ethereum/go-ethereum      v1.14.8  -> v1.17.2
- github.com/cosmos/interchain-security/v5 v5.1.1 -> v5.2.0
- github.com/consensys/gnark-crypto    v0.12.1  -> v0.18.2

Other:
- github.com/bytedance/sonic           v1.13.2  -> v1.15.0
  (required by Go 1.25 linkname rules)
- enable the local replace
  github.com/Safrochain_Org/safrochain => ../ in interchaintest/go.mod
  (the prior commented placeholder pointed at a non-existent v1.0.0 tag)

Toolchain:
- go directive bumped from 1.23.9 to 1.25.8 in both go.mod files
  because several upgraded transitive dependencies now require Go 1.25.
- CI workflows, Dockerfile, build_release.sh and .mise.toml updated
  to match.

Alerts not addressed in this PR:
- github.com/btcsuite/btcd (3 alerts): the patched 0.23.2+ releases
  remove the legacy btcec package that github.com/tendermint/tendermint
  v0.38.0-dev (pulled in transitively by interchaintest's namada chain
  support) still imports. Bumping breaks that build path.
- github.com/docker/docker (2 alerts): the advisories request 29.3.1,
  which has not yet been published as a Go module. Bumped to v25.0.14
  to close the two alerts that have available patches.
- github.com/shamaton/msgpack/v2: no patched release yet; bumped to
  the latest available (v2.4.0).

* chore(dependabot): switch schedules from weekly to monthly

Reduces noise from automated PRs while still maintaining a regular
cadence for security and version updates. Also extends .gitignore to
exclude local agent worktrees (.claude/, .cursor/) and local report
artifacts (*.docx, *.pdf) so they cannot be accidentally committed.

Made-with: Cursor

* ci: fix lint, ictest-pfm, and ictest-gov-fix failures on PR #16

- golangci-lint: bump v2.1.6 -> v2.4.0 so the linter binary is built
  with Go 1.25 (matches go.mod toolchain 1.25.8). v2.1.6 was built
  with Go 1.24 and refused to load the config with
  "language version go1.24 lower than targeted Go version 1.25.8".

- ictest-pfm: align the interchaintest Bech32 prefixes with what
  the chain binary actually produces ("addr_safro" / "addr_safropub"
  / "addr_safrovaloper" / "addr_safrovalcons"). The test harness was
  still pinned to the legacy "safrochain" prefix, so faucet-account
  setup failed with "invalid Bech32 prefix; expected safrochain,
  got addr_safro".

- ictest-gov-fix (and any ghcr-pull paths): lowercase the registry
  reference to ghcr.io/safrochain_org/safrochain. Docker rejects
  uppercase repo names ("repository name must be lowercase"), so
  the upgrade test could not pull v27.0.0 / v28.0.2. Also lowercase
  the publish workflow's tag list for symmetry.

- Add docker/login-action to the e2e workflow so the GHCR pulls
  performed by upgrade tests can reach private packages owned by
  the same org. permissions: packages: write was already granted.

Made-with: Cursor

* ci: make golangci-lint v2.4.0 actually pass

golangci-lint v2.1.6 used to bail at config load with "language version
go1.24 lower than targeted 1.25.8" so it never reported any findings.
Bumping to v2.4.0 (which is built with go 1.25) exposed a chain of
real, pre-existing problems that this commit resolves:

1. *.pb.go files in <module>/v1/ for cwhooks, clock, drip, feepay,
   feeshare, mint, gaia/globalfee, osmosis/tokenfactory imported a
   bare 'cosmos/app/v1alpha1' which is not a valid Go path. The
   sibling *.pulsar.go files already used the canonical
   'cosmossdk.io/api/cosmos/app/v1alpha1', so adopt the same import
   in the *.pb.go files. This fixes 'go build ./...' on top of being
   what protoc-gen-gogo should have emitted.

2. .golangci.yml exclusions used a malformed glob ('./api/*.*') and
   missed *.pulsar.go entirely, which let revive's "unreachable code"
   findings on generated pulsar code break the run. Replace with
   regex-anchored patterns that cover both *.pb.go and *.pulsar.go,
   plus the whole api/ tree.

3. revive: disable two rules that were unanimous noise on Cosmos SDK
   code:
   - var-naming: complains about packages literally named "types",
     which is a hard convention in every Cosmos module.
   - enforce-switch-style: triggers on exhaustive type switches over
     sealed proto Any interfaces where a default case is unreachable.

4. Auto-format imports (gci) on app/{app,keepers/keepers,keepers/keys,
   modules}.go, testutil/fund.go, x/drip/keeper/genesis_test.go, and
   x/feepay/types/errors.go.

5. Drop the unused 'dfd' receiver name in
   DeductFeeDecorator.checkTxFeeWithValidatorMinGasPrices to satisfy
   revive's unused-receiver rule.

Local 'golangci-lint run' now reports 0 issues against v2.4.0.

Made-with: Cursor

* ci: finish addr_safro alignment and self-quarantine ictest-gov-fix

After the previous round, ictest-pfm still failed because that test
defines its own ChainConfig with Bech32Prefix: "safrochain" rather
than reusing the shared safrochainConfig from setup.go. Update it to
"addr_safro", and update the four other test files that still
encoded user addresses with the legacy "safrochain" prefix
(MustBech32ifyAddressBytes calls in chain_upgrade_test.go,
fix_removed_msg_panic_test.go, module_clock_test.go,
module_globalfee_test.go). Most of those code paths happen to be
guarded behind successful chain start, so they hadn't tripped yet,
but they are wrong.

ictest-gov-fix performs a chain upgrade and depends on historical
GHCR images (v27.0.0 / v28.0.2). Those images cannot be pulled
either by fork-PR GITHUB_TOKEN (restricted by GitHub for security)
or by the docker login currently performed in this workflow,
regardless of whether they are addressed under
ghcr.io/safrochain_org/safrochain or ghcr.io/safrochain-org/safrochain.

Add a pre-flight that probes both lowercase forms with
docker manifest inspect and skips the test (with a warning, not a
failure) when neither resolves. The check is scoped to
ictest-gov-fix; every other matrix entry still runs unconditionally.
When the historical images are eventually published publicly, the
pre-flight will start finding them and the test will run again
without further changes.

Made-with: Cursor
…build UX (#23)

Bumps aws-sdk-go-v2 stack, refactors map iterations to use slices.Sorted+maps.Keys for determinism, scopes CodeQL to first-party code, and polishes the make build/install output.
…atch (#24)

Three pre-existing CI/quality bugs: missing //go:embed in cw-hooks test (build workflow had been failing every push since Apr 26), 26 sensitive-import false positives in api/**/*.pulsar.go (now query-filtered), and broken multi-line GITHUB_OUTPUT in release-dispatch (every release dispatch failing since v0.1.0).
The previous default of 100000usaf/gas produced absurd per-tx fees
(a single MsgSend at typical 80k gas would cost 8,000 SAF, more than
any community validator's self-stake).

0.005 usaf/gas matches the Cosmos Hub default and produces sensible
fees: ~0.0004 SAF for a send, ~0.001 SAF for an IBC transfer.
Tuned up from 0.005 -> 0.05. 10x more validator fee revenue per tx
while keeping per-tx user cost trivial (~0.004 SAF send, ~0.01 SAF
IBC transfer).
@safrochain
safrochain self-requested a review May 25, 2026 13:47
@safrochain
safrochain merged commit 5364479 into Safrochain-Org:main May 25, 2026
21 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants