mukan-sdk/x/genutil/collect.go
Mukan Erkin Törük abb1ff956e
Some checks are pending
Build SimApp / build (amd64) (push) Waiting to run
Build SimApp / build (arm64) (push) Waiting to run
CodeQL / Analyze (push) Waiting to run
Build & Push / build (push) Waiting to run
Run Gosec / Gosec (push) Waiting to run
Lint / golangci-lint (push) Waiting to run
Checks dependencies and mocks generation / Check go mod tidy (push) Waiting to run
Checks dependencies and mocks generation / Check up to date mocks (push) Waiting to run
System Tests / setup (push) Waiting to run
System Tests / test-system (push) Blocked by required conditions
System Tests / test-system-legacy (push) Blocked by required conditions
Tests / Code Coverage / split-test-files (push) Waiting to run
Tests / Code Coverage / tests (00) (push) Blocked by required conditions
Tests / Code Coverage / tests (01) (push) Blocked by required conditions
Tests / Code Coverage / tests (02) (push) Blocked by required conditions
Tests / Code Coverage / tests (03) (push) Blocked by required conditions
Tests / Code Coverage / test-integration (push) Waiting to run
Tests / Code Coverage / test-e2e (push) Waiting to run
Tests / Code Coverage / repo-analysis (push) Blocked by required conditions
Tests / Code Coverage / test-sim-nondeterminism (push) Waiting to run
Tests / Code Coverage / test-clientv2 (push) Waiting to run
Tests / Code Coverage / test-core (push) Waiting to run
Tests / Code Coverage / test-depinject (push) Waiting to run
Tests / Code Coverage / test-errors (push) Waiting to run
Tests / Code Coverage / test-math (push) Waiting to run
Tests / Code Coverage / test-schema (push) Waiting to run
Tests / Code Coverage / test-collections (push) Waiting to run
Tests / Code Coverage / test-cosmovisor (push) Waiting to run
Tests / Code Coverage / test-confix (push) Waiting to run
Tests / Code Coverage / test-store (push) Waiting to run
Tests / Code Coverage / test-log (push) Waiting to run
Tests / Code Coverage / test-x-tx (push) Waiting to run
Tests / Code Coverage / test-x-nft (push) Waiting to run
Tests / Code Coverage / test-x-circuit (push) Waiting to run
Tests / Code Coverage / test-x-feegrant (push) Waiting to run
Tests / Code Coverage / test-x-evidence (push) Waiting to run
Tests / Code Coverage / test-x-upgrade (push) Waiting to run
Tests / Code Coverage / test-tools-benchmark (push) Waiting to run
refactor: complete sovereign stack cleanup — all github.com upstream refs purged
2026-05-11 03:46:06 +03:00

180 lines
5.6 KiB
Go

package genutil
import (
"encoding/json"
"errors"
"fmt"
"os"
"path/filepath"
"runtime"
"sort"
"strings"
cfg "git.cw.tr/mukan-network/mukan-consensus/config"
"git.cw.tr/mukan-network/mukan-sdk/client"
"git.cw.tr/mukan-network/mukan-sdk/codec"
sdkruntime "git.cw.tr/mukan-network/mukan-sdk/runtime"
sdk "git.cw.tr/mukan-network/mukan-sdk/types"
bankexported "git.cw.tr/mukan-network/mukan-sdk/x/bank/exported"
"git.cw.tr/mukan-network/mukan-sdk/x/genutil/types"
stakingtypes "git.cw.tr/mukan-network/mukan-sdk/x/staking/types"
)
// GenAppStateFromConfig gets the genesis app state from the config
func GenAppStateFromConfig(cdc codec.JSONCodec, txEncodingConfig client.TxEncodingConfig,
config *cfg.Config, initCfg types.InitConfig, genesis *types.AppGenesis, genBalIterator types.GenesisBalancesIterator,
validator types.MessageValidator, valAddrCodec sdkruntime.ValidatorAddressCodec,
) (appState json.RawMessage, err error) {
// process genesis transactions, else create default genesis.json
appGenTxs, persistentPeers, err := CollectTxs(
cdc, txEncodingConfig.TxJSONDecoder(), config.Moniker, initCfg.GenTxsDir, genesis, genBalIterator, validator, valAddrCodec)
if err != nil {
return appState, err
}
config.P2P.PersistentPeers = persistentPeers
cfg.WriteConfigFile(filepath.Join(config.RootDir, "config", "config.toml"), config)
// if there are no gen txs to be processed, return the default empty state
if len(appGenTxs) == 0 {
return appState, errors.New("there must be at least one genesis tx")
}
// create the app state
appGenesisState, err := types.GenesisStateFromAppGenesis(genesis)
if err != nil {
return appState, err
}
appGenesisState, err = SetGenTxsInAppGenesisState(cdc, txEncodingConfig.TxJSONEncoder(), appGenesisState, appGenTxs)
if err != nil {
return appState, err
}
appState, err = json.MarshalIndent(appGenesisState, "", " ")
if err != nil {
return appState, err
}
genesis.AppState = appState
err = ExportGenesisFile(genesis, config.GenesisFile())
return appState, err
}
// CollectTxs processes and validates application's genesis Txs and returns
// the list of appGenTxs, and persistent peers required to generate genesis.json.
func CollectTxs(cdc codec.JSONCodec, txJSONDecoder sdk.TxDecoder, moniker, genTxsDir string,
genesis *types.AppGenesis, genBalIterator types.GenesisBalancesIterator,
validator types.MessageValidator, valAddrCodec sdkruntime.ValidatorAddressCodec,
) (appGenTxs []sdk.Tx, persistentPeers string, err error) {
// prepare a map of all balances in genesis state to then validate
// against the validators addresses
var appState map[string]json.RawMessage
if err := json.Unmarshal(genesis.AppState, &appState); err != nil {
return appGenTxs, persistentPeers, err
}
var fos []os.DirEntry
fos, err = os.ReadDir(genTxsDir)
if err != nil {
return appGenTxs, persistentPeers, err
}
balancesMap := make(map[string]bankexported.GenesisBalance)
genBalIterator.IterateGenesisBalances(
cdc, appState,
func(balance bankexported.GenesisBalance) (stop bool) {
addr := balance.GetAddress()
balancesMap[addr] = balance
return false
},
)
// addresses and IPs (and port) validator server info
var addressesIPs []string
for _, fo := range fos {
if fo.IsDir() {
continue
}
if !strings.HasSuffix(fo.Name(), ".json") {
continue
}
// get the genTx
jsonRawTx, err := os.ReadFile(filepath.Join(genTxsDir, fo.Name()))
if err != nil {
return appGenTxs, persistentPeers, err
}
genTx, err := types.ValidateAndGetGenTx(jsonRawTx, txJSONDecoder, validator)
if err != nil {
return appGenTxs, persistentPeers, err
}
appGenTxs = append(appGenTxs, genTx)
// the memo flag is used to store
// the ip and node-id, for example this may be:
// "528fd3df22b31f4969b05652bfe8f0fe921321d5@192.168.2.37:26656"
memoTx, ok := genTx.(sdk.TxWithMemo)
if !ok {
return appGenTxs, persistentPeers, fmt.Errorf("expected TxWithMemo, got %T", genTx)
}
nodeAddrIP := memoTx.GetMemo()
// genesis transactions must be single-message
msgs := genTx.GetMsgs()
// TODO abstract out staking message validation back to staking
msg := msgs[0].(*stakingtypes.MsgCreateValidator)
// validate validator addresses and funds against the accounts in the state
valAddr, err := valAddrCodec.StringToBytes(msg.ValidatorAddress)
if err != nil {
return appGenTxs, persistentPeers, err
}
valAccAddr := sdk.AccAddress(valAddr).String()
delBal, delOk := balancesMap[valAccAddr]
if !delOk {
_, file, no, ok := runtime.Caller(1)
if ok {
fmt.Printf("CollectTxs-1, called from %s#%d\n", file, no)
}
return appGenTxs, persistentPeers, fmt.Errorf("account %s balance not in genesis state: %+v", valAccAddr, balancesMap)
}
_, valOk := balancesMap[sdk.AccAddress(valAddr).String()]
if !valOk {
_, file, no, ok := runtime.Caller(1)
if ok {
fmt.Printf("CollectTxs-2, called from %s#%d - %s\n", file, no, sdk.AccAddress(msg.ValidatorAddress).String())
}
return appGenTxs, persistentPeers, fmt.Errorf("account %s balance not in genesis state: %+v", valAddr, balancesMap)
}
if delBal.GetCoins().AmountOf(msg.Value.Denom).LT(msg.Value.Amount) {
return appGenTxs, persistentPeers, fmt.Errorf(
"insufficient fund for delegation %v: %v < %v",
delBal.GetAddress(), delBal.GetCoins().AmountOf(msg.Value.Denom), msg.Value.Amount,
)
}
// exclude itself from persistent peers
if msg.Description.Moniker != moniker {
addressesIPs = append(addressesIPs, nodeAddrIP)
}
}
sort.Strings(addressesIPs)
persistentPeers = strings.Join(addressesIPs, ",")
return appGenTxs, persistentPeers, nil
}