@@ -2,11 +2,9 @@ package server
22
33import (
44 "bufio"
5- "bytes"
65 "context"
76 "crypto/sha256"
87 "encoding/json"
9- "errors"
108 "fmt"
119 "io"
1210 "net"
@@ -57,7 +55,7 @@ import (
5755 servercmtlog "github.com/cosmos/cosmos-sdk/server/log"
5856 "github.com/cosmos/cosmos-sdk/server/types"
5957 "github.com/cosmos/cosmos-sdk/telemetry"
60- "github.com/cosmos/cosmos-sdk/types/bech32 "
58+ sdktypes "github.com/cosmos/cosmos-sdk/types"
6159 "github.com/cosmos/cosmos-sdk/types/mempool"
6260 "github.com/cosmos/cosmos-sdk/version"
6361 genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
@@ -120,6 +118,8 @@ const (
120118 KeyNewValAddr = "new-validator-addr"
121119 KeyUserPubKey = "user-pub-key"
122120 KeyTriggerTestnetUpgrade = "trigger-testnet-upgrade"
121+
122+ defaultNewChainID = "injective-devnetify-1389"
123123)
124124
125125type ExtendedValidator struct {
@@ -666,12 +666,7 @@ func startApp(svrCtx *Context, appCreator types.AppCreator, opts StartCmdOptions
666666 }
667667
668668 if isTestnet , ok := svrCtx .Viper .Get (KeyIsTestnet ).(bool ); ok && isTestnet {
669-
670- pubKey , ok := svrCtx .Viper .Get (KeyUserPubKey ).(* sdked25519.PubKey )
671- if ! ok {
672- return app , traceCleanupFn , errors .New ("no public key found in server ctx, or its not an ed25519 public key" )
673- }
674- validators , err := MockTestnetifyExtendedValidators (pubKey )
669+ validators , err := MockTestnetifyExtendedValidators (svrCtx .Config )
675670 if err != nil {
676671 return app , traceCleanupFn , err
677672 }
@@ -794,48 +789,18 @@ you want to test the upgrade handler itself.
794789// Testnetify modifies both state and blockStore, allowing the provided operator address and local validator key to control the network
795790// that the state in the data folder represents. The chainID of the local genesis file is modified to match the provided chainID.
796791func Testnetify (ctx * Context , testnetAppCreator types.AppCreator , db dbm.DB , traceWriter io.WriteCloser , validators []ExtendedValidator ) (types.Application , error ) {
797- // Modify app genesis chain ID and save to genesis file.
798- // Create the codec and registry
799- interfaceRegistry := codectypes .NewInterfaceRegistry ()
800-
801- // Register the ed25519 PubKey type
802- var pkI * cryptotypes.PubKey
803- interfaceRegistry .RegisterInterface ("cosmos.crypto.PubKey" , pkI )
804- interfaceRegistry .RegisterImplementations (pkI , & sdked25519.PubKey {})
805-
806- // Also register the PrivKey
807- var privI * cryptotypes.PrivKey
808- interfaceRegistry .RegisterInterface ("cosmos.crypto.PrivKey" , privI )
809- interfaceRegistry .RegisterImplementations (privI , & sdked25519.PrivKey {})
810-
811- cdc := codec .NewProtoCodec (interfaceRegistry )
812-
813- // Unpack every validator
814- for i := range validators {
815- if err := validators [i ].UnpackInterfaces (cdc .InterfaceRegistry ()); err != nil {
816- return nil , fmt .Errorf ("failed to unpack interfaces: %w" , err )
817- }
818- }
819792
820793 config := ctx .Config
821-
822- if len ( validators ) == 0 {
823- return nil , fmt .Errorf ("no validators provided" )
794+ newChainID , ok := ctx . Viper . Get ( KeyNewChainID ).( string )
795+ if ! ok {
796+ return nil , fmt .Errorf ("expected string for key %s" , KeyNewChainID )
824797 }
825-
826- // Modify app genesis chain ID and save to genesis file.
827- genFilePath := config .GenesisFile ()
828- appGen , err := genutiltypes .AppGenesisFromFile (genFilePath )
829- if err != nil {
830- return nil , err
798+ if newChainID == "" {
799+ newChainID = defaultNewChainID
831800 }
832- appGen .ChainID = "injective-1389"
833801
834- if err := appGen .ValidateAndComplete (); err != nil {
835- return nil , err
836- }
837- if err := appGen .SaveAs (genFilePath ); err != nil {
838- return nil , err
802+ if len (validators ) == 0 {
803+ return nil , fmt .Errorf ("no validators provided" )
839804 }
840805
841806 // Regenerate addrbook.json to prevent peers on old network from causing error logs.
@@ -867,17 +832,6 @@ func Testnetify(ctx *Context, testnetAppCreator types.AppCreator, db dbm.DB, tra
867832 defer blockStore .Close ()
868833 defer stateDB .Close ()
869834
870- privValidator , err := pvm .LoadOrGenFilePV (config .PrivValidatorKeyFile (), config .PrivValidatorStateFile (), nil )
871- if err != nil {
872- return nil , err
873- }
874-
875- userPubKey , err := privValidator .GetPubKey ()
876- if err != nil {
877- return nil , err
878- }
879- validatorAddress := userPubKey .Address ()
880-
881835 stateStore := sm .NewStore (stateDB , sm.StoreOptions {
882836 DiscardABCIResponses : config .Storage .DiscardABCIResponses ,
883837 })
@@ -942,14 +896,24 @@ func Testnetify(ctx *Context, testnetAppCreator types.AppCreator, db dbm.DB, tra
942896 if block == nil {
943897 return nil , fmt .Errorf ("no block found at height %d" , blockStore .Height ())
944898 }
945- block .ChainID = "injective-1389"
946- state .ChainID = "injective-1389"
947- genDoc .ChainID = "injective-1389"
899+
900+ block .ChainID = newChainID
901+ state .ChainID = newChainID
902+ genDoc .ChainID = newChainID
903+
948904 block .LastBlockID = state .LastBlockID
949905 block .LastCommit .BlockID = state .LastBlockID
906+ block .LastCommit .Height = blockStore .Height ()
950907
951908 newValSet := & cmttypes.ValidatorSet {Validators : []* cmttypes.Validator {}}
952909
910+ totalValidators := len (validators ) // e.g. 60
911+ powerReduction := sdkmath .NewInt (1_000_000_000_000_000_000 ) // 10^18
912+ totalVotingPower := int64 (10000 )
913+ votingPowerPerValidator := totalVotingPower / int64 (totalValidators )
914+ var commitSigs []cmttypes.CommitSig
915+ var seenCommitsSigs []cmttypes.CommitSig
916+
953917 for i , extVal := range validators {
954918 // Get the tendermint pubkey from the validator
955919 pubKey , err := GetTmPubKeyFromExtendedValidator (extVal )
@@ -994,98 +958,69 @@ func Testnetify(ctx *Context, testnetAppCreator types.AppCreator, db dbm.DB, tra
994958
995959 // Modify the block's lastCommit to be signed only by our validator
996960 // Instead of trying to extend existing signatures, just create a fresh signature array
997- block .LastCommit .Signatures = []cmttypes.CommitSig {
998- {
999- BlockIDFlag : cmttypes .BlockIDFlagCommit ,
1000- ValidatorAddress : valAddress ,
1001- Signature : vote .Signature ,
1002- Timestamp : vote .Timestamp ,
1003- },
1004- }
1005-
1006- // Load the seenCommit of the lastBlockHeight and modify it to be signed from our validator
1007- seenCommit := blockStore .LoadSeenCommit (state .LastBlockHeight )
1008- if seenCommit == nil {
1009- // If there's no seen commit, we can't proceed with this validator
1010- continue
961+ commitSig := cmttypes.CommitSig {
962+ BlockIDFlag : cmttypes .BlockIDFlagCommit ,
963+ ValidatorAddress : valAddress ,
964+ Signature : vote .Signature ,
965+ Timestamp : vote .Timestamp ,
1011966 }
1012-
1013- seenCommit .BlockID = state .LastBlockID
1014- seenCommit .Round = vote .Round
967+ commitSigs = append (commitSigs , commitSig )
1015968
1016969 // Just create a fresh signature array with one signature
1017- seenCommit .Signatures = []cmttypes.CommitSig {
1018- {
1019- BlockIDFlag : cmttypes .BlockIDFlagCommit ,
1020- ValidatorAddress : valAddress ,
1021- Signature : vote .Signature ,
1022- Timestamp : vote .Timestamp ,
1023- },
970+ seenCommitSig := cmttypes.CommitSig {
971+ BlockIDFlag : cmttypes .BlockIDFlagCommit ,
972+ ValidatorAddress : valAddress ,
973+ Signature : vote .Signature ,
974+ Timestamp : vote .Timestamp ,
1024975 }
976+ seenCommitsSigs = append (seenCommitsSigs , seenCommitSig )
1025977
1026- err = blockStore .SaveSeenCommit (state .LastBlockHeight , seenCommit )
1027- if err != nil {
1028- return nil , err
1029- }
978+ // To ensure Tokens field aligns with staking module (i.e., Tokens = VotingPower * PowerReduction)
979+ tokensPerValidator := sdkmath .NewInt (votingPowerPerValidator ).Mul (powerReduction )
980+ extVal .Validator .Tokens = tokensPerValidator
1030981
1031- powerReduction := sdkmath .NewInt (1_000_000_000_000_000_000 ) // 10^18
1032- votingPower := extVal .Validator .Tokens .Quo (powerReduction ).Int64 ()
1033- // Create ValidatorSet struct containing just our valdiator.
1034982 newVal := & cmttypes.Validator {
1035983 Address : valAddress ,
1036984 PubKey : pubKey ,
1037- VotingPower : votingPower ,
985+ VotingPower : votingPowerPerValidator ,
1038986 }
987+
1039988 newValSet .Validators = append (newValSet .Validators , newVal )
1040989 }
1041990 newValSet .Proposer = newValSet .Validators [0 ]
1042991
1043- // Directly update the privval key file to match our validator - this ensures the node
1044- // uses the exact same validator key for consensus
1045- if len (validators ) > 0 {
1046- // Get the public key from our validator
1047- pubKey , err := GetTmPubKeyFromExtendedValidator (validators [0 ])
1048- if err != nil {
1049- return nil , fmt .Errorf ("failed to get validator pubkey for privval file update: %w" , err )
1050- }
1051-
1052- // Load the private validator key
1053- pvKeyFile := config .PrivValidatorKeyFile ()
1054- pvStateFile := config .PrivValidatorStateFile ()
1055- ctx .Logger .Info ("Checking private validator files" ,
1056- "keyFile" , pvKeyFile ,
1057- "stateFile" , pvStateFile ,
1058- "expected_validator_addr" , fmt .Sprintf ("%X" , pubKey .Address ()))
1059-
1060- pv := pvm .LoadOrGenFilePV (pvKeyFile , pvStateFile )
1061-
1062- // Log the loaded private validator details
1063- pvPubKey , err := pv .GetPubKey ()
1064- if err != nil {
1065- ctx .Logger .Error ("Failed to get private validator pubkey" , "err" , err )
1066- } else {
1067- pvAddress := pvPubKey .Address ()
1068- ctx .Logger .Info ("Loaded private validator" ,
1069- "address" , fmt .Sprintf ("%X" , pvAddress ),
1070- "pubkey" , fmt .Sprintf ("%X" , pvPubKey .Bytes ()))
1071-
1072- // Check if the private validator address matches our expected validator address
1073- if ! bytes .Equal (pvAddress , pubKey .Address ()) {
1074- ctx .Logger .Error ("Private validator address does not match expected validator address" ,
1075- "pv_address" , fmt .Sprintf ("%X" , pvAddress ),
1076- "expected_address" , fmt .Sprintf ("%X" , pubKey .Address ()))
1077- } else {
1078- ctx .Logger .Info ("Private validator address matches expected validator address" ,
1079- "address" , fmt .Sprintf ("%X" , pvAddress ))
1080- }
1081- }
1082- }
1083-
1084992 // Replace all valSets in state to be the valSet with just our validator.
1085993 state .Validators = newValSet
1086994 state .LastValidators = newValSet
1087995 state .NextValidators = newValSet
1088996 state .LastHeightValidatorsChanged = blockStore .Height ()
997+ block .LastCommit .Signatures = commitSigs
998+ // Load the seenCommit of the lastBlockHeight and modify it to be signed from our validator
999+ seenCommit := blockStore .LoadSeenCommit (state .LastBlockHeight )
1000+ if seenCommit == nil {
1001+ // If there's no seen commit, we can't proceed with this validator
1002+ return nil , fmt .Errorf ("no seen commit found for height %d" , state .LastBlockHeight )
1003+ }
1004+
1005+ seenCommit .BlockID = state .LastBlockID
1006+ seenCommit .Round = 0
1007+ seenCommit .Signatures = seenCommitsSigs
1008+ seenCommit .Height = block .Height
1009+ // Fake last seen commit since we are starting from arbitrary height, This ensures the consensus engine doesn’t fail during the handshake or proposal step
1010+ err = blockStore .SaveSeenCommit (state .LastBlockHeight , seenCommit )
1011+ if err != nil {
1012+ return nil , fmt .Errorf ("failed to save seen commit: %w" , err )
1013+ }
1014+
1015+ // We need to ensure that priv_validator_state.json is set to first round, this prevent cometbft from crashing
1016+ // In cases when we are copying a state from a previous network, that is alrady on round > 0
1017+ pv := pvm .LoadFilePV (config .PrivValidatorKeyFile (), config .PrivValidatorStateFile ())
1018+ pv .LastSignState .Height = state .LastBlockHeight - 1
1019+ pv .LastSignState .Round = 0
1020+ pv .LastSignState .Step = 0
1021+ pv .LastSignState .Signature = nil
1022+ pv .LastSignState .SignBytes = nil
1023+ pv .Save ()
10891024
10901025 err = stateStore .Save (state )
10911026 if err != nil {
@@ -1226,27 +1161,23 @@ func GetTmPubKeyFromExtendedValidator(ev ExtendedValidator) (tmcrypto.PubKey, er
12261161 return nil , fmt .Errorf ("could not extract public key from validator" )
12271162}
12281163
1229- func MockTestnetifyExtendedValidators (pubKey * sdked25519.PubKey ) ([]ExtendedValidator , error ) {
1230- // Create Any type from the input pubKey
1231- pubKeyAny , err := codectypes .NewAnyWithValue (pubKey )
1164+ func MockTestnetifyExtendedValidators (cfg * cmtcfg.Config ) ([]ExtendedValidator , error ) {
1165+ // Load local node's priv validator key
1166+ privValidator := pvm .LoadFilePV (cfg .PrivValidatorKeyFile (), cfg .PrivValidatorStateFile ())
1167+ pubKey , err := privValidator .GetPubKey ()
12321168 if err != nil {
1233- return nil , err
1169+ return nil , fmt . Errorf ( "failed to get pubkey from priv validator: %w" , err )
12341170 }
1235-
1236- // Get the validator operator address with injvaloper prefix
1237- addressBytes := pubKey .Address ().Bytes ()
1238- valAddr , err := bech32 .ConvertAndEncode ("injvaloper" , addressBytes )
1171+ pubKeySdk := & sdked25519.PubKey {Key : pubKey .Bytes ()}
1172+ validatorAddress := pubKey .Address ().Bytes ()
1173+ pubkeyAny , err := codectypes .NewAnyWithValue (pubKeySdk )
12391174 if err != nil {
12401175 return nil , err
12411176 }
12421177
1243- // Create a placeholder private key - this is needed for the ExtendedValidator struct
1244- // but won't be used for actual signing since we're using the node's private key
1245- placeholderPrivKey := tmcryptoed25519 .GenPrivKey ()
1246-
12471178 validator := stakingtypes.Validator {
1248- OperatorAddress : valAddr ,
1249- ConsensusPubkey : pubKeyAny ,
1179+ OperatorAddress : sdktypes . ValAddress ( validatorAddress ). String () ,
1180+ ConsensusPubkey : pubkeyAny ,
12501181 Jailed : false ,
12511182 Status : stakingtypes .Bonded ,
12521183 Tokens : sdkmath .NewInt (9000000000000000000 ),
@@ -1264,15 +1195,10 @@ func MockTestnetifyExtendedValidators(pubKey *sdked25519.PubKey) ([]ExtendedVali
12641195 MinSelfDelegation : sdkmath .OneInt (),
12651196 }
12661197
1267- // Print validation info to confirm we're using the correct key
1268- sdkPubKeyBytes := pubKey .Key
1269- fmt .Printf ("Using validator with pubkey: %X\n " , sdkPubKeyBytes )
1270- fmt .Printf ("Validator operator address: %s\n " , valAddr )
1271-
12721198 validators := []ExtendedValidator {
12731199 {
12741200 Validator : validator ,
1275- PrivKey : placeholderPrivKey ,
1201+ PrivKey : privValidator . Key . PrivKey ,
12761202 },
12771203 }
12781204 return validators , nil
0 commit comments