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
180 lines
5.6 KiB
Go
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
|
|
}
|