diff --git a/.github/workflows/humanode-build.yml b/.github/workflows/humanode-build.yml new file mode 100644 index 0000000..70afd3d --- /dev/null +++ b/.github/workflows/humanode-build.yml @@ -0,0 +1,39 @@ +# Humanode's build of safe-cli: upstream's tests on Ganache, as upstream's ci.yml runs them, then the wheel owners +# install, with a SHA-256 manifest. Runs on every pull request and on main. +name: humanode-build +on: + pull_request: + push: + branches: [main] + tags: ["humanode-*"] + workflow_dispatch: +permissions: + contents: read +jobs: + build: + runs-on: ubuntu-24.04 + steps: + # Upstream's own test setup (safe-cli .github/workflows/ci.yml): a local Ganache chain, and the actions pinned to + # the same commits upstream pins. + - name: Create Ganache network + run: docker network create ganache + - name: Run Ganache + run: docker run --detach --publish 8545:8545 --network ganache -e DOCKER=true trufflesuite/ganache:latest --defaultBalanceEther 10000 --gasLimit 10000000 -a 30 --chain.chainId 1337 --chain.networkId 1337 -d + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1, as upstream pins it + - uses: astral-sh/setup-uv@18d369b23da25a81e9458561248e1aafff6a70fa # v10.3.1, as upstream pins it + with: + python-version: "3.13" + - name: Install exactly the locked dependencies + run: uv sync --group dev --all-extras --frozen + - name: Upstream tests + run: uv run pytest -rxXs + - name: Build the wheel + run: uv build --wheel + - name: Manifest + run: | + sha256sum dist/*.whl > dist/SHA256SUMS + echo "commit $GITHUB_SHA" >> dist/SHA256SUMS + - uses: actions/upload-artifact@v4 + with: + name: safe-cli-${{ github.ref_name }} + path: dist/ diff --git a/src/safe_cli/gas_price.py b/src/safe_cli/gas_price.py index b3bf6c0..4e96c33 100644 --- a/src/safe_cli/gas_price.py +++ b/src/safe_cli/gas_price.py @@ -18,6 +18,11 @@ LEGACY_GAS_PRICE_FLAG = "--legacy-gas-price" +# Humanode's build: on these chains --legacy-gas-price is on by default (SAFE_CLI_LEGACY_GAS=0 turns it off). Humanode +# charges a fixed fee per gas, which eth_gasPrice reports, while eth_feeHistory forecasts 0.875 x that fee after a +# quiet block, so EIP-1559 fees taken from fee history are refused. +LEGACY_GAS_DEFAULT_CHAIN_IDS = {5234} + def parse_gwei(value: str) -> int: """ @@ -64,7 +69,10 @@ def legacy_gas_price(w3: Web3) -> int | None: fixed = os.environ.get("SAFE_CLI_LEGACY_GAS_PRICE", "") if fixed: return parse_gwei(fixed) - if os.environ.get("SAFE_CLI_LEGACY_GAS", "") == "1": + setting = os.environ.get("SAFE_CLI_LEGACY_GAS", "") + if setting == "1" or ( + setting != "0" and w3.eth.chain_id in LEGACY_GAS_DEFAULT_CHAIN_IDS + ): return w3.eth.gas_price return None diff --git a/tests/test_gas_price.py b/tests/test_gas_price.py index ab794d7..83472b7 100644 --- a/tests/test_gas_price.py +++ b/tests/test_gas_price.py @@ -41,6 +41,7 @@ def test_take_flag_rejects_bad_price(self): def test_legacy_gas_price(self): w3 = mock.Mock() w3.eth.gas_price = 123 + w3.eth.chain_id = 1 with mock.patch.dict(os.environ, {}, clear=True): self.assertIsNone(legacy_gas_price(w3)) with mock.patch.dict(os.environ, {"SAFE_CLI_LEGACY_GAS": "1"}, clear=True): @@ -51,3 +52,15 @@ def test_legacy_gas_price(self): clear=True, ): self.assertEqual(legacy_gas_price(w3), 2 * 10**9) + + def test_default_on_humanode(self): + w3 = mock.Mock() + w3.eth.gas_price = 715_000 * 10**9 + w3.eth.chain_id = 5234 + with mock.patch.dict(os.environ, {}, clear=True): + self.assertEqual(legacy_gas_price(w3), 715_000 * 10**9) + with mock.patch.dict(os.environ, {"SAFE_CLI_LEGACY_GAS": "0"}, clear=True): + self.assertIsNone(legacy_gas_price(w3)) + w3.eth.chain_id = 1 + with mock.patch.dict(os.environ, {}, clear=True): + self.assertIsNone(legacy_gas_price(w3))