Skip to content
Draft
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
23 changes: 23 additions & 0 deletions app/upgrades/upgrades_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,29 @@ func TestV1201CarriesEVMBringupOnAllNetworks(t *testing.T) {
}
}

// TestV1202RegistersOnAllNetworks asserts v1.20.2 is wired up everywhere.
//
// NOTE: this test previously also asserted `config.StoreUpgrade == nil`, on the
// reasoning that v1.20.2 is a migration-only carrier. That premise was correct
// for testnet and WRONG for mainnet, and the mainnet-shaped devnet rehearsal
// disproved it: mainnet is still on 1.12.0 with NO EVM stores, so declaring no
// StoreUpgrades made every validator crash-loop with
//
// panic: version of store evmigration mismatch root store's version;
// expected 155 got 0; new stores should be added using StoreUpgrades
//
// v1.20.2 therefore declares the EVM store additions on every network, paired
// with the add-only store loader that mounts only the keys missing from
// committed state. Store expectations now live in v1_20_2_store_test.go.
func TestV1202RegistersOnAllNetworks(t *testing.T) {
for _, chainID := range []string{"lumera-mainnet-1", "lumera-testnet-2", "lumera-devnet-1"} {
params := newTestUpgradeParams(chainID)
config, found := SetupUpgrades(upgrade_v1_20_2.UpgradeName, params)
require.True(t, found)
require.NotNil(t, config.Handler, "v1.20.2 must register a handler on %s", chainID)
}
}

func newTestUpgradeParams(chainID string) appParams.AppUpgradeParams {
return appParams.AppUpgradeParams{
ChainID: chainID,
Expand Down
11 changes: 11 additions & 0 deletions app/upgrades/v1_20_2/upgrade_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package v1_20_2

import (
"testing"

"github.com/stretchr/testify/require"
)

func TestUpgradeName(t *testing.T) {
require.Equal(t, "v1.20.2", UpgradeName)
}
7 changes: 4 additions & 3 deletions devnet/scripts/account-registry.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

ACCOUNTS_DISPLAY_DENOM_DEFAULT="${ACCOUNTS_DISPLAY_DENOM_DEFAULT:-lume}"
ACCOUNTS_DISPLAY_EXPONENT_DEFAULT="${ACCOUNTS_DISPLAY_EXPONENT_DEFAULT:-6}"
ACCOUNTS_FILE_MODE="${ACCOUNTS_FILE_MODE:-600}"

accounts_registry_init() {
local node_status_dir="$1"
Expand All @@ -28,7 +29,7 @@ ensure_accounts_registry() {
if [[ ! -f "${ACCOUNTS_FILE}" ]]; then
printf '[]\n' >"${ACCOUNTS_FILE}"
fi
chmod 644 "${ACCOUNTS_FILE}"
chmod "${ACCOUNTS_FILE_MODE}" "${ACCOUNTS_FILE}"
}

accounts_registry_parse_coin() {
Expand Down Expand Up @@ -148,9 +149,9 @@ accounts_registry_upsert() {
}]
| sort_by(.name)
' "${ACCOUNTS_FILE}" >"${tmp_file}"
chmod 644 "${tmp_file}"
chmod "${ACCOUNTS_FILE_MODE}" "${tmp_file}"
mv "${tmp_file}" "${ACCOUNTS_FILE}"
chmod 644 "${ACCOUNTS_FILE}"
chmod "${ACCOUNTS_FILE_MODE}" "${ACCOUNTS_FILE}"
}

accounts_registry_get_field() {
Expand Down
4 changes: 3 additions & 1 deletion devnet/scripts/submit-upgrade-proposal.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@
# Configuration
VERSION="$1"
UPGRADE_HEIGHT="$2"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
DEVNET_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
CHAIN_ID="lumera-devnet-1"
SERVICE="supernova_validator_1" # primary validator
LUMERA_SHARED="/tmp/${CHAIN_ID}/shared"
KEYRING="test"
HOST_PROPOSAL_FILE="${LUMERA_SHARED}/upgrade_${VERSION}.json"
CONTAINER_PROPOSAL_FILE="/shared/upgrade_${VERSION}.json"
COMPOSE_FILE="../docker-compose.yml"
COMPOSE_FILE="${DEVNET_ROOT}/docker-compose.yml"
STATUS_DIR="${LUMERA_SHARED}/status"
ACCOUNT_REGISTRY_FILE="${STATUS_DIR}/${SERVICE}/accounts.json"

Expand Down
4 changes: 3 additions & 1 deletion devnet/scripts/vote-all.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ if [ -z "$1" ]; then
fi

# Configuration
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
DEVNET_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
CHAIN_ID="lumera-devnet-1"
KEYRING_BACKEND="test"
PROPOSAL_ID="$1"
SERVICE_NAME="supernova_validator_1"
COMPOSE_FILE="../docker-compose.yml"
COMPOSE_FILE="${DEVNET_ROOT}/docker-compose.yml"
FEES="5000ulume"
# Gas configuration — use a fixed gas amount by default. `--gas auto` simulates
# a gov vote at ~57.9k and even with a 1.3x bump lands right at the real usage
Expand Down
35 changes: 35 additions & 0 deletions devnet/tests/common/account_registry_permissions_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package common

import (
"os/exec"
"path/filepath"
"testing"
)

func TestAccountRegistryContainingMnemonicsIsOwnerOnly(t *testing.T) {
scriptPath, err := filepath.Abs("../../scripts/account-registry.sh")
if err != nil {
t.Fatalf("resolve account registry script path: %v", err)
}

const scenario = `
set -euo pipefail
source "$1"
accounts_registry_init "$2"

ensure_accounts_registry
[[ "$(stat -c '%a' "$ACCOUNTS_FILE")" == "600" ]]

chmod 644 "$ACCOUNTS_FILE"
ensure_accounts_registry
[[ "$(stat -c '%a' "$ACCOUNTS_FILE")" == "600" ]]

accounts_registry_upsert test-account lumera1fixture 'fixture mnemonic' cosmos 1ulume genesis ABC123
[[ "$(stat -c '%a' "$ACCOUNTS_FILE")" == "600" ]]
jq -e '. == [{name:"test-account",address:"lumera1fixture",mnemonic:"fixture mnemonic",type:"cosmos",funded:{display_amount:"0.000001",display_denom:"lume",base_amount:"1",base_denom:"ulume"},funding_key:"genesis",funding_txhash:"ABC123",created_at:(.[] | .created_at)}]' "$ACCOUNTS_FILE" >/dev/null
`
cmd := exec.Command("bash", "-c", scenario, "account-registry-permissions-test", scriptPath, t.TempDir())
if out, err := cmd.CombinedOutput(); err != nil {
t.Fatalf("account registry must remain owner-only across every write path: %v\n%s", err, out)
}
}
19 changes: 19 additions & 0 deletions devnet/tests/common/upgrade_proposal_script_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package common
import (
"os/exec"
"path/filepath"
"strings"
"testing"
)

Expand All @@ -20,6 +21,24 @@ func runUpgradeProposalScriptScenario(t *testing.T, testScript string) {
}
}

func TestUpgradeProposalComposePathIsIndependentOfWorkingDirectory(t *testing.T) {
scriptPath, err := filepath.Abs("../../scripts/submit-upgrade-proposal.sh")
if err != nil {
t.Fatalf("resolve proposal script path: %v", err)
}
expected := filepath.Clean(filepath.Join(filepath.Dir(scriptPath), "..", "docker-compose.yml"))

cmd := exec.Command("bash", "-c", `source "$1"; printf '%s\n' "$COMPOSE_FILE"`, "upgrade-proposal-path-test", scriptPath)
cmd.Dir = t.TempDir()
out, err := cmd.CombinedOutput()
if err != nil {
t.Fatalf("source proposal script: %v\n%s", err, out)
}
if got := strings.TrimSpace(string(out)); got != expected {
t.Fatalf("compose path must be script-relative: got %q, want %q", got, expected)
}
}

func TestUpgradeProposalRestoresKeyForPersistedMigratedAddress(t *testing.T) {
const testScript = `
source "$1"
Expand Down
32 changes: 32 additions & 0 deletions devnet/tests/common/vote_all_script_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package common

import (
"os"
"path/filepath"
"strings"
"testing"
)

func TestVoteAllComposePathIsScriptRelative(t *testing.T) {
scriptPath, err := filepath.Abs("../../scripts/vote-all.sh")
if err != nil {
t.Fatalf("resolve vote script path: %v", err)
}
contents, err := os.ReadFile(scriptPath)
if err != nil {
t.Fatalf("read vote script: %v", err)
}
script := string(contents)
for _, required := range []string{
`SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"`,
`DEVNET_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"`,
`COMPOSE_FILE="${DEVNET_ROOT}/docker-compose.yml"`,
} {
if !strings.Contains(script, required) {
t.Fatalf("vote script must contain %q", required)
}
}
if strings.Contains(script, `COMPOSE_FILE="../docker-compose.yml"`) {
t.Fatal("vote script must not resolve compose path from caller working directory")
}
}
Loading
Loading