github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/ibc-go/testing/chain.go (about) 1 package ibctesting 2 3 import ( 4 "bytes" 5 "fmt" 6 "testing" 7 "time" 8 9 "github.com/fibonacci-chain/fbc/libs/tendermint/crypto" 10 11 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/client" 12 types2 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/codec/types" 13 ibcmsg "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/ibc-adapter" 14 ibc_tx "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth/ibc-tx" 15 "github.com/fibonacci-chain/fbc/libs/tendermint/crypto/secp256k1" 16 17 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/codec" 18 //cryptotypes "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/crypto/types" 19 sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types" 20 sdkerrors "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/errors" 21 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth" 22 authtypes "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth/exported" 23 24 //banktypes "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/bank/types" 25 capabilitykeeper "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/capability/keeper" 26 capabilitytypes "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/capability/types" 27 28 stakingtypes "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/staking/types" 29 abci "github.com/fibonacci-chain/fbc/libs/tendermint/abci/types" 30 tmproto "github.com/fibonacci-chain/fbc/libs/tendermint/abci/types" 31 "github.com/fibonacci-chain/fbc/libs/tendermint/crypto/tmhash" 32 tmprototypes "github.com/fibonacci-chain/fbc/libs/tendermint/proto/types" 33 tmtypes "github.com/fibonacci-chain/fbc/libs/tendermint/types" 34 tmprotoversion "github.com/fibonacci-chain/fbc/libs/tendermint/version" 35 tmversion "github.com/fibonacci-chain/fbc/libs/tendermint/version" 36 "github.com/stretchr/testify/require" 37 38 "github.com/fibonacci-chain/fbc/app/crypto/ethsecp256k1" 39 apptypes "github.com/fibonacci-chain/fbc/app/types" 40 okcapptypes "github.com/fibonacci-chain/fbc/app/types" 41 clienttypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/02-client/types" 42 commitmenttypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/23-commitment/types" 43 host "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/24-host" 44 "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/exported" 45 "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/types" 46 ibctmtypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/light-clients/07-tendermint/types" 47 "github.com/fibonacci-chain/fbc/libs/ibc-go/testing/mock" 48 "github.com/fibonacci-chain/fbc/libs/ibc-go/testing/simapp" 49 ) 50 51 type TestChainI interface { 52 TxConfig() client.TxConfig 53 T() *testing.T 54 App() TestingApp 55 GetContext() sdk.Context 56 GetContextPointer() *sdk.Context 57 GetClientState(clientID string) exported.ClientState 58 QueryProof(key []byte) ([]byte, clienttypes.Height) 59 QueryConsensusStateProof(clientID string) ([]byte, clienttypes.Height) 60 GetConsensusState(clientID string, height exported.Height) (exported.ConsensusState, bool) 61 GetPrefix() commitmenttypes.MerklePrefix 62 LastHeader() *ibctmtypes.Header 63 QueryServer() types.QueryService 64 ChainID() string 65 Codec() *codec.CodecProxy 66 SenderAccount() sdk.Account 67 SenderAccountPV() crypto.PrivKey 68 SenderAccountPVBZ() []byte 69 CurrentTMClientHeader() *ibctmtypes.Header 70 ExpireClient(amount time.Duration) 71 CurrentHeader() tmproto.Header 72 CurrentHeaderTime(time.Time) 73 NextBlock() 74 BeginBlock() 75 UpdateNextBlock() 76 77 CreateTMClientHeader(chainID string, blockHeight int64, trustedHeight clienttypes.Height, timestamp time.Time, tmValSet, tmTrustedVals *tmtypes.ValidatorSet, signers []tmtypes.PrivValidator) *ibctmtypes.Header 78 Vals() *tmtypes.ValidatorSet 79 Signers() []tmtypes.PrivValidator 80 GetSimApp() *simapp.SimApp 81 GetChannelCapability(portID, channelID string) *capabilitytypes.Capability 82 CreateChannelCapability(scopedKeeper capabilitykeeper.ScopedKeeper, portID, channelID string) 83 SendMsgs(msgs ...ibcmsg.Msg) (*sdk.Result, error) 84 QueryUpgradeProof(key []byte, height uint64) ([]byte, clienttypes.Height) 85 Coordinator() *Coordinator 86 QueryProofAtHeight(key []byte, height int64) ([]byte, clienttypes.Height) 87 ConstructUpdateTMClientHeaderWithTrustedHeight(counterparty TestChainI, clientID string, trustedHeight clienttypes.Height) (*ibctmtypes.Header, error) 88 ConstructUpdateTMClientHeader(counterparty TestChainI, clientID string) (*ibctmtypes.Header, error) 89 sendMsgs(msgs ...ibcmsg.Msg) error 90 GetValsAtHeight(height int64) (*tmtypes.ValidatorSet, bool) 91 CreatePortCapability(scopedKeeper capabilitykeeper.ScopedKeeper, portID string) 92 GetPortCapability(portID string) *capabilitytypes.Capability 93 94 SenderAccounts() []SenderAccount 95 } 96 97 // TestChain is a testing struct that wraps a simapp with the last TM Header, the current ABCI 98 // header and the validators of the TestChain. It also contains a field called ChainID. This 99 // is the clientID that *other* chains use to refer to this TestChain. The SenderAccount 100 // is used for delivering transactions through the application state. 101 // NOTE: the actual application uses an empty chain-id for ease of testing. 102 type TestChain struct { 103 t *testing.T 104 privKeyBz []byte 105 context sdk.Context 106 107 coordinator *Coordinator 108 TApp TestingApp 109 chainID string 110 lastHeader *ibctmtypes.Header // header for last block height committed 111 currentHeader tmproto.Header // header for current block height 112 // QueryServer types.QueryServer 113 queryServer types.QueryService 114 txConfig client.TxConfig 115 codec *codec.CodecProxy 116 117 vals *tmtypes.ValidatorSet 118 signers []tmtypes.PrivValidator 119 120 senderPrivKey crypto.PrivKey 121 senderAccount authtypes.Account 122 123 senderAccounts []SenderAccount 124 } 125 126 var MaxAccounts = 10 127 128 type SenderAccount struct { 129 SenderPrivKey crypto.PrivKey 130 SenderAccount auth.Account 131 } 132 133 // NewTestChain initializes a new TestChain instance with a single validator set using a 134 // generated private key. It also creates a sender account to be used for delivering transactions. 135 // 136 // The first block height is committed to state in order to allow for client creations on 137 // counterparty chains. The TestChain will return with a block height starting at 2. 138 // 139 // Time management is handled by the Coordinator in order to ensure synchrony between chains. 140 // Each update of any chain increments the block header time for all chains by 5 seconds. 141 func NewTestChain(t *testing.T, coord *Coordinator, chainID string) TestChainI { 142 // generate validator private/public key 143 privVal := mock.NewPV() 144 pubKey, err := privVal.GetPubKey() 145 require.NoError(t, err) 146 147 senderAccs := []SenderAccount{} 148 149 // generate genesis accounts 150 for i := 0; i < MaxAccounts; i++ { 151 senderPrivKey := secp256k1.GenPrivKey() 152 i, ok := sdk.NewIntFromString("92233720368547758080") 153 require.True(t, ok) 154 balance := sdk.NewCoins(apptypes.NewPhotonCoin(i)) 155 156 acc := auth.NewBaseAccount(senderPrivKey.PubKey().Address().Bytes(), balance, senderPrivKey.PubKey(), 0, 0) 157 //amount, ok := sdk.NewIntFromString("10000000000000000000") 158 //require.True(t, ok) 159 160 // add sender account 161 //balance := banktypes.Balance{ 162 // Address: acc.GetAddress().String(), 163 // Coins: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, amount)), 164 //} 165 166 //genAccs = append(genAccs, acc) 167 //genBals = append(genBals, balance) 168 169 senderAcc := SenderAccount{ 170 SenderAccount: acc, 171 SenderPrivKey: senderPrivKey, 172 } 173 174 senderAccs = append(senderAccs, senderAcc) 175 } 176 177 // create validator set with single validator 178 validator := tmtypes.NewValidator(pubKey, 1) 179 valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) 180 signers := []tmtypes.PrivValidator{privVal} 181 182 // generate genesis account 183 senderPrivKey := secp256k1.GenPrivKey() 184 //var pubkeyBytes secp256k1.PubKeySecp256k1 185 //copy(pubkeyBytes[:], senderPrivKey.PubKey().Bytes()) 186 187 i, ok := sdk.NewIntFromString("92233720368547758080") 188 require.True(t, ok) 189 balance := sdk.NewCoins(apptypes.NewPhotonCoin(i)) 190 var genesisAcc authtypes.GenesisAccount 191 genesisAcc = auth.NewBaseAccount(senderPrivKey.PubKey().Address().Bytes(), balance, senderPrivKey.PubKey(), 0, 0) 192 193 //amount, ok := sdk.NewIntFromString("10000000000000000000") 194 //require.True(t, ok) 195 196 //fromBalance := suite.App().AccountKeeper.GetAccount(suite.ctx, cmFrom).GetCoins() 197 //var account *apptypes.EthAccount 198 //balance = sdk.NewCoins(fbexchaintypes.NewPhotonCoin(amount)) 199 //addr := sdk.AccAddress(pubKey.Address()) 200 //baseAcc := auth.NewBaseAccount(addr, balance, pubKey, 10, 50) 201 //account = &apptypes.EthAccount{ 202 // BaseAccount: baseAcc, 203 // CodeHash: []byte{1, 2}, 204 //} 205 //fmt.Println(account) 206 //// balance := banktypes.Balance{ 207 //// Address: acc.GetAddress().String(), 208 //// Coins: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, amount)), 209 //// } 210 211 app := SetupWithGenesisValSet(t, chainID, valSet, []authtypes.GenesisAccount{genesisAcc}, balance) 212 213 // create current header and call begin block 214 header := tmproto.Header{ 215 ChainID: chainID, 216 Height: 1, 217 Time: coord.CurrentTime.UTC(), 218 } 219 220 txConfig := app.TxConfig() 221 222 // create an account to send transactions from 223 tchain := &TestChain{ 224 t: t, 225 privKeyBz: senderPrivKey[:], 226 coordinator: coord, 227 chainID: chainID, 228 TApp: app, 229 currentHeader: header, 230 queryServer: app.GetIBCKeeper(), 231 txConfig: txConfig, 232 codec: app.AppCodec(), 233 vals: valSet, 234 signers: signers, 235 senderPrivKey: &senderPrivKey, 236 senderAccount: genesisAcc, 237 senderAccounts: senderAccs, 238 } 239 240 //coord.UpdateNextBlock(tchain) 241 coord.CommitBlock(tchain) 242 // 243 //coord.UpdateNextBlock(tchain) 244 mockModuleAcc := tchain.GetSimApp().SupplyKeeper.GetModuleAccount(tchain.GetContext(), mock.ModuleName) 245 require.NotNil(t, mockModuleAcc) 246 247 return tchain 248 } 249 250 func NewTestEthChain(t *testing.T, coord *Coordinator, chainID string) *TestChain { 251 // generate validator private/public key 252 privVal := mock.NewPV() 253 pubKey, err := privVal.GetPubKey() 254 require.NoError(t, err) 255 256 // create validator set with single validator 257 validator := tmtypes.NewValidator(pubKey, 1) 258 valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) 259 signers := []tmtypes.PrivValidator{privVal} 260 261 //Kb := keys.NewInMemory(hd.EthSecp256k1Options()...) 262 // generate genesis account 263 //info, err = Kb.CreateAccount(name, mnemonic, "", passWd, hdPath, hd.EthSecp256k1) 264 senderPrivKey, _ := ethsecp256k1.GenerateKey() //secp256k1.GenPrivKey() 265 266 ethPubkey := senderPrivKey.PubKey() //ethsecp256k1.PrivKey(senderPrivKey.Bytes()).PubKey() 267 268 i, ok := sdk.NewIntFromString("92233720368547758080") 269 require.True(t, ok) 270 balance := sdk.NewCoins(apptypes.NewPhotonCoin(i)) 271 272 genesisAcc := &okcapptypes.EthAccount{ 273 BaseAccount: auth.NewBaseAccount(ethPubkey.Address().Bytes(), balance, ethPubkey, 0, 0), 274 CodeHash: []byte{}, 275 } 276 // 277 //senderPrivKey.PubKey().Address().Bytes() 278 279 app := SetupWithGenesisValSet(t, chainID, valSet, []authtypes.GenesisAccount{genesisAcc}, balance) 280 281 // create current header and call begin block 282 header := tmproto.Header{ 283 ChainID: chainID, 284 Height: 1, 285 Time: coord.CurrentTime.UTC(), 286 } 287 288 txConfig := app.TxConfig() 289 290 // create an account to send transactions from 291 return &TestChain{ 292 t: t, 293 coordinator: coord, 294 chainID: chainID, 295 TApp: app, 296 currentHeader: header, 297 queryServer: app.GetIBCKeeper(), 298 txConfig: txConfig, 299 codec: app.AppCodec(), 300 vals: valSet, 301 signers: signers, 302 senderPrivKey: &senderPrivKey, 303 senderAccount: genesisAcc, 304 privKeyBz: senderPrivKey[:], 305 } 306 307 //coord.UpdateNextBlock(tchain) 308 //coord.CommitBlock(tchain) 309 // 310 //coord.UpdateNextBlock(tchain) 311 312 } 313 func (chain *TestChain) SenderAccounts() []SenderAccount { 314 return chain.senderAccounts 315 } 316 317 // GetContext returns the current context for the application. 318 func (chain *TestChain) GetContext() sdk.Context { 319 return chain.App().GetBaseApp().NewContext(false, chain.CurrentHeader()) 320 } 321 322 func (chain *TestChain) TxConfig() client.TxConfig { 323 interfaceRegistry := types2.NewInterfaceRegistry() 324 marshaler := codec.NewProtoCodec(interfaceRegistry) 325 chain.txConfig = ibc_tx.NewTxConfig(marshaler, ibc_tx.DefaultSignModes) 326 return chain.txConfig 327 } 328 329 // GetSimApp returns the SimApp to allow usage ofnon-interface fields. 330 // CONTRACT: This function should not be called by third parties implementing 331 // their own SimApp. 332 func (chain *TestChain) GetSimApp() *simapp.SimApp { 333 app, ok := chain.TApp.(*simapp.SimApp) 334 require.True(chain.t, ok) 335 336 return app 337 } 338 339 // QueryProof performs an abci query with the given key and returns the proto encoded merkle proof 340 // for the query and the height at which the proof will succeed on a tendermint verifier. 341 func (chain *TestChain) QueryProof(key []byte) ([]byte, clienttypes.Height) { 342 return chain.QueryProofAtHeight(key, chain.App().LastBlockHeight()) 343 } 344 345 // QueryProof performs an abci query with the given key and returns the proto encoded merkle proof 346 // for the query and the height at which the proof will succeed on a tendermint verifier. 347 func (chain *TestChain) QueryProofAtHeight(key []byte, height int64) ([]byte, clienttypes.Height) { 348 res := chain.App().Query(abci.RequestQuery{ 349 Path: fmt.Sprintf("store/%s/key", host.StoreKey), 350 Height: height - 1, 351 Data: key, 352 Prove: true, 353 }) 354 355 merkleProof, err := commitmenttypes.ConvertProofs(res.GetProof()) 356 require.NoError(chain.t, err) 357 358 proof, err := chain.App().AppCodec().GetProtocMarshal().MarshalBinaryBare(&merkleProof) 359 require.NoError(chain.t, err) 360 361 revision := clienttypes.ParseChainID(chain.ChainID()) 362 363 // proof height + 1 is returned as the proof created corresponds to the height the proof 364 // was created in the IAVL tree. Tendermint and subsequently the clients that rely on it 365 // have heights 1 above the IAVL tree. Thus we return proof height + 1 366 return proof, clienttypes.NewHeight(revision, uint64(res.Height)+1) 367 } 368 369 // QueryUpgradeProof performs an abci query with the given key and returns the proto encoded merkle proof 370 // for the query and the height at which the proof will succeed on a tendermint verifier. 371 func (chain *TestChain) QueryUpgradeProof(key []byte, height uint64) ([]byte, clienttypes.Height) { 372 res := chain.App().Query(abci.RequestQuery{ 373 Path: "store/upgrade/key", 374 Height: int64(height - 1), 375 Data: key, 376 Prove: true, 377 }) 378 379 // merkleProof, err := commitmenttypes.ConvertProofs(res.ProofOps) 380 merkleProof, err := commitmenttypes.ConvertProofs(res.GetProof()) 381 require.NoError(chain.t, err) 382 383 // proof, err := chain.App().AppCodec().Marshal(&merkleProof) 384 // require.NoError(chain.t, err) 385 proof, err := chain.App().AppCodec().GetProtocMarshal().MarshalBinaryBare(&merkleProof) 386 require.NoError(chain.t, err) 387 388 revision := clienttypes.ParseChainID(chain.ChainID()) 389 390 // proof height + 1 is returned as the proof created corresponds to the height the proof 391 // was created in the IAVL tree. Tendermint and subsequently the clients that rely on it 392 // have heights 1 above the IAVL tree. Thus we return proof height + 1 393 return proof, clienttypes.NewHeight(revision, uint64(res.Height+1)) 394 } 395 396 // QueryConsensusStateProof performs an abci query for a consensus state 397 // stored on the given clientID. The proof and consensusHeight are returned. 398 func (chain *TestChain) QueryConsensusStateProof(clientID string) ([]byte, clienttypes.Height) { 399 clientState := chain.GetClientState(clientID) 400 401 consensusHeight := clientState.GetLatestHeight().(clienttypes.Height) 402 consensusKey := host.FullConsensusStateKey(clientID, consensusHeight) 403 proofConsensus, _ := chain.QueryProof(consensusKey) 404 405 return proofConsensus, consensusHeight 406 } 407 408 // NextBlock sets the last header to the current header and increments the current header to be 409 // at the next block height. It does not update the time as that is handled by the Coordinator. 410 // 411 // CONTRACT: this function must only be called after app.Commit() occurs 412 func (chain *TestChain) NextBlock() { 413 // set the last header to the current header 414 // use nil trusted fields 415 chain.SetLastHeader(chain.CurrentTMClientHeader()) 416 417 // increment the current header 418 chain.SetCurrentHeader(tmproto.Header{ 419 ChainID: chain.ChainID(), 420 Height: chain.App().LastBlockHeight() + 1, 421 AppHash: chain.App().LastCommitID().Hash, 422 // NOTE: the time is increased by the coordinator to maintain time synchrony amongst 423 // chains. 424 Time: chain.CurrentHeader().Time, 425 ValidatorsHash: chain.Vals().Hash(chain.App().LastBlockHeight() + 1), 426 NextValidatorsHash: chain.Vals().Hash(chain.App().LastBlockHeight() + 1), 427 }) 428 429 chain.App().BeginBlock(abci.RequestBeginBlock{Header: chain.CurrentHeader()}) 430 } 431 432 func (chain *TestChain) BeginBlock() { 433 chain.App().BeginBlock(abci.RequestBeginBlock{Header: chain.CurrentHeader()}) 434 } 435 436 func (chain *TestChain) UpdateNextBlock() { 437 chain.SetLastHeader(chain.CurrentTMClientHeader()) 438 439 // increment the current header 440 chain.SetCurrentHeader(tmproto.Header{ 441 ChainID: chain.ChainID(), 442 Height: chain.App().LastBlockHeight() + 1, 443 AppHash: chain.App().LastCommitID().Hash, 444 // NOTE: the time is increased by the coordinator to maintain time synchrony amongst 445 // chains. 446 Time: chain.CurrentHeader().Time, 447 ValidatorsHash: chain.Vals().Hash(chain.App().LastBlockHeight() + 1), 448 NextValidatorsHash: chain.Vals().Hash(chain.App().LastBlockHeight() + 1), 449 }) 450 chain.App().BeginBlock(abci.RequestBeginBlock{Header: chain.CurrentHeader()}) 451 } 452 453 // sendMsgs delivers a transaction through the application without returning the result. 454 func (chain *TestChain) sendMsgs(msgs ...ibcmsg.Msg) error { 455 _, err := chain.SendMsgs(msgs...) 456 return err 457 } 458 459 // SendMsgs delivers a transaction through the application. It updates the senders sequence 460 // number and updates the TestChain's headers. It returns the result and error if one 461 // occurred. 462 func (chain *TestChain) SendMsgs(msgs ...ibcmsg.Msg) (*sdk.Result, error) { 463 464 // ensure the chain has the latest time 465 chain.Coordinator().UpdateTimeForChain(chain) 466 _, r, err := simapp.SignAndDeliver( 467 chain.t, 468 chain.TxConfig(), 469 chain.App().GetBaseApp(), 470 //chain.GetContextPointer().BlockHeader(), 471 chain.CurrentHeader(), 472 msgs, 473 chain.ChainID(), 474 []uint64{chain.SenderAccount().GetAccountNumber()}, 475 []uint64{chain.SenderAccount().GetSequence()}, 476 true, true, chain.senderPrivKey, 477 ) 478 if err != nil { 479 return nil, err 480 } 481 482 // SignAndDeliver calls app.Commit() 483 chain.NextBlock() 484 485 // increment sequence for successful transaction execution 486 chain.SenderAccount().SetSequence(chain.SenderAccount().GetSequence() + 1) 487 488 chain.Coordinator().IncrementTime() 489 490 return r, nil 491 } 492 493 // GetClientState retrieves the client state for the provided clientID. The client is 494 // expected to exist otherwise testing will fail. 495 func (chain *TestChain) GetClientState(clientID string) exported.ClientState { 496 clientState, found := chain.App().GetIBCKeeper().ClientKeeper.GetClientState(chain.GetContext(), clientID) 497 require.True(chain.t, found) 498 499 return clientState 500 } 501 502 // GetConsensusState retrieves the consensus state for the provided clientID and height. 503 // It will return a success boolean depending on if consensus state exists or not. 504 func (chain *TestChain) GetConsensusState(clientID string, height exported.Height) (exported.ConsensusState, bool) { 505 return chain.App().GetIBCKeeper().ClientKeeper.GetClientConsensusState(chain.GetContext(), clientID, height) 506 } 507 508 // GetValsAtHeight will return the validator set of the chain at a given height. It will return 509 // a success boolean depending on if the validator set exists or not at that height. 510 func (chain *TestChain) GetValsAtHeight(height int64) (*tmtypes.ValidatorSet, bool) { 511 histInfo, ok := chain.App().GetStakingKeeper().GetHistoricalInfo(chain.GetContext(), height) 512 if !ok { 513 return nil, false 514 } 515 516 valSet := stakingtypes.Validators(histInfo.ValSet) 517 518 validators := make([]*tmtypes.Validator, len(valSet)) 519 for i, val := range valSet { 520 validators[i] = tmtypes.NewValidator(val.GetConsPubKey(), 1) 521 } 522 523 return tmtypes.NewValidatorSet(validators), true 524 } 525 526 // GetAcknowledgement retrieves an acknowledgement for the provided packet. If the 527 // acknowledgement does not exist then testing will fail. 528 func (chain *TestChain) GetAcknowledgement(packet exported.PacketI) []byte { 529 ack, found := chain.App().GetIBCKeeper().ChannelKeeper.GetPacketAcknowledgement(chain.GetContext(), packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence()) 530 require.True(chain.t, found) 531 532 return ack 533 } 534 535 // GetPrefix returns the prefix for used by a chain in connection creation 536 func (chain *TestChain) GetPrefix() commitmenttypes.MerklePrefix { 537 return commitmenttypes.NewMerklePrefix(chain.App().GetIBCKeeper().ConnectionKeeper.GetCommitmentPrefix().Bytes()) 538 } 539 540 // ConstructUpdateTMClientHeader will construct a valid 07-tendermint Header to update the 541 // light client on the source chain. 542 func (chain *TestChain) ConstructUpdateTMClientHeader(counterparty TestChainI, clientID string) (*ibctmtypes.Header, error) { 543 return chain.ConstructUpdateTMClientHeaderWithTrustedHeight(counterparty, clientID, clienttypes.ZeroHeight()) 544 } 545 546 // ConstructUpdateTMClientHeader will construct a valid 07-tendermint Header to update the 547 // light client on the source chain. 548 func (chain *TestChain) ConstructUpdateTMClientHeaderWithTrustedHeight(counterparty TestChainI, clientID string, trustedHeight clienttypes.Height) (*ibctmtypes.Header, error) { 549 header := counterparty.LastHeader() 550 // Relayer must query for LatestHeight on client to get TrustedHeight if the trusted height is not set 551 if trustedHeight.IsZero() { 552 trustedHeight = chain.GetClientState(clientID).GetLatestHeight().(clienttypes.Height) 553 } 554 var ( 555 tmTrustedVals *tmtypes.ValidatorSet 556 ok bool 557 ) 558 // Once we get TrustedHeight from client, we must query the validators from the counterparty chain 559 // If the LatestHeight == LastHeader.Height, then TrustedValidators are current validators 560 // If LatestHeight < LastHeader.Height, we can query the historical validator set from HistoricalInfo 561 if trustedHeight == counterparty.LastHeader().GetHeight() { 562 tmTrustedVals = counterparty.Vals() 563 } else { 564 // NOTE: We need to get validators from counterparty at height: trustedHeight+1 565 // since the last trusted validators for a header at height h 566 // is the NextValidators at h+1 committed to in header h by 567 // NextValidatorsHash 568 tmTrustedVals, ok = counterparty.GetValsAtHeight(int64(trustedHeight.RevisionHeight + 1)) 569 if !ok { 570 return nil, sdkerrors.Wrapf(ibctmtypes.ErrInvalidHeaderHeight, "could not retrieve trusted validators at trustedHeight: %d", trustedHeight) 571 } 572 } 573 // inject trusted fields into last header 574 // for now assume revision number is 0 575 header.TrustedHeight = trustedHeight 576 577 trustedVals, err := tmTrustedVals.ToProto() 578 if err != nil { 579 return nil, err 580 } 581 header.TrustedValidators = trustedVals 582 583 return header, nil 584 585 } 586 587 // ExpireClient fast forwards the chain's block time by the provided amount of time which will 588 // expire any clients with a trusting period less than or equal to this amount of time. 589 func (chain *TestChain) ExpireClient(amount time.Duration) { 590 chain.Coordinator().IncrementTimeBy(amount) 591 } 592 593 // CurrentTMClientHeader creates a TM header using the current header parameters 594 // on the chain. The trusted fields in the header are set to nil. 595 func (chain *TestChain) CurrentTMClientHeader() *ibctmtypes.Header { 596 return chain.CreateTMClientHeader(chain.chainID, chain.CurrentHeader().Height, clienttypes.Height{}, chain.CurrentHeader().Time, chain.Vals(), nil, chain.Signers()) 597 } 598 599 // CreateTMClientHeader creates a TM header to update the TM client. Args are passed in to allow 600 // caller flexibility to use params that differ from the chain. 601 func (chain *TestChain) CreateTMClientHeader(chainID string, blockHeight int64, trustedHeight clienttypes.Height, timestamp time.Time, tmValSet, tmTrustedVals *tmtypes.ValidatorSet, signers []tmtypes.PrivValidator) *ibctmtypes.Header { 602 var ( 603 valSet *tmprototypes.ValidatorSet 604 trustedVals *tmprototypes.ValidatorSet 605 ) 606 require.NotNil(chain.t, tmValSet) 607 608 vsetHash := tmValSet.Hash(blockHeight) 609 610 tmHeader := tmtypes.Header{ 611 Version: tmprotoversion.Consensus{Block: tmversion.BlockProtocol, App: 2}, 612 ChainID: chainID, 613 Height: blockHeight, 614 Time: timestamp, 615 LastBlockID: MakeBlockID(make([]byte, tmhash.Size), 10_000, make([]byte, tmhash.Size)), 616 LastCommitHash: chain.App().LastCommitID().Hash, 617 DataHash: tmhash.Sum([]byte("data_hash")), 618 ValidatorsHash: vsetHash, 619 NextValidatorsHash: vsetHash, 620 ConsensusHash: tmhash.Sum([]byte("consensus_hash")), 621 AppHash: chain.CurrentHeader().AppHash, 622 LastResultsHash: tmhash.Sum([]byte("last_results_hash")), 623 EvidenceHash: tmhash.Sum([]byte("evidence_hash")), 624 ProposerAddress: tmValSet.Proposer.Address, //nolint:staticcheck 625 } 626 hhash := tmHeader.Hash() 627 blockID := MakeBlockID(hhash, 3, tmhash.Sum([]byte("part_set"))) 628 voteSet := tmtypes.NewVoteSet(chainID, blockHeight, 1, tmtypes.PrecommitType, tmValSet) 629 630 commit, err := tmtypes.MakeCommit(blockID, blockHeight, 1, voteSet, signers, timestamp) 631 require.NoError(chain.t, err) 632 633 signedHeader := &tmtypes.SignedHeader{ 634 Header: &tmHeader, 635 Commit: commit, 636 } 637 638 if tmValSet != nil { 639 valSet, err = tmValSet.ToProto() 640 if err != nil { 641 panic(err) 642 } 643 } 644 645 if tmTrustedVals != nil { 646 trustedVals, err = tmTrustedVals.ToProto() 647 if err != nil { 648 panic(err) 649 } 650 } 651 652 // The trusted fields may be nil. They may be filled before relaying messages to a client. 653 // The relayer is responsible for querying client and injecting appropriate trusted fields. 654 return &ibctmtypes.Header{ 655 SignedHeader: signedHeader.ToProto(), 656 ValidatorSet: valSet, 657 TrustedHeight: trustedHeight, 658 TrustedValidators: trustedVals, 659 } 660 } 661 662 // MakeBlockID copied unimported test functions from tmtypes to use them here 663 func MakeBlockID(hash []byte, partSetSize uint32, partSetHash []byte) tmtypes.BlockID { 664 return tmtypes.BlockID{ 665 Hash: hash, 666 PartsHeader: tmtypes.PartSetHeader{ 667 Total: int(partSetSize), 668 Hash: partSetHash, 669 }, 670 } 671 } 672 673 // CreateSortedSignerArray takes two PrivValidators, and the corresponding Validator structs 674 // (including voting power). It returns a signer array of PrivValidators that matches the 675 // sorting of ValidatorSet. 676 // The sorting is first by .VotingPower (descending), with secondary index of .Address (ascending). 677 func CreateSortedSignerArray(altPrivVal, suitePrivVal tmtypes.PrivValidator, 678 altVal, suiteVal *tmtypes.Validator) []tmtypes.PrivValidator { 679 680 switch { 681 case altVal.VotingPower > suiteVal.VotingPower: 682 return []tmtypes.PrivValidator{altPrivVal, suitePrivVal} 683 case altVal.VotingPower < suiteVal.VotingPower: 684 return []tmtypes.PrivValidator{suitePrivVal, altPrivVal} 685 default: 686 if bytes.Compare(altVal.Address, suiteVal.Address) == -1 { 687 return []tmtypes.PrivValidator{altPrivVal, suitePrivVal} 688 } 689 return []tmtypes.PrivValidator{suitePrivVal, altPrivVal} 690 } 691 } 692 693 // CreatePortCapability binds and claims a capability for the given portID if it does not 694 // already exist. This function will fail testing on any resulting error. 695 // NOTE: only creation of a capbility for a transfer or mock port is supported 696 // Other applications must bind to the port in InitGenesis or modify this code. 697 func (chain *TestChain) CreatePortCapability(scopedKeeper capabilitykeeper.ScopedKeeper, portID string) { 698 // check if the portId is already binded, if not bind it 699 _, ok := chain.App().GetScopedIBCKeeper().GetCapability(chain.GetContext(), host.PortPath(portID)) 700 if !ok { 701 // create capability using the IBC capability keeper 702 cap, err := chain.App().GetScopedIBCKeeper().NewCapability(chain.GetContext(), host.PortPath(portID)) 703 require.NoError(chain.t, err) 704 705 // claim capability using the scopedKeeper 706 err = scopedKeeper.ClaimCapability(chain.GetContext(), cap, host.PortPath(portID)) 707 require.NoError(chain.t, err) 708 } 709 710 chain.App().Commit(abci.RequestCommit{}) 711 712 chain.NextBlock() 713 } 714 715 // GetPortCapability returns the port capability for the given portID. The capability must 716 // exist, otherwise testing will fail. 717 func (chain *TestChain) GetPortCapability(portID string) *capabilitytypes.Capability { 718 cap, ok := chain.App().GetScopedIBCKeeper().GetCapability(chain.GetContext(), host.PortPath(portID)) 719 require.True(chain.t, ok) 720 721 return cap 722 } 723 724 // CreateChannelCapability binds and claims a capability for the given portID and channelID 725 // if it does not already exist. This function will fail testing on any resulting error. The 726 // scoped keeper passed in will claim the new capability. 727 func (chain *TestChain) CreateChannelCapability(scopedKeeper capabilitykeeper.ScopedKeeper, portID, channelID string) { 728 capName := host.ChannelCapabilityPath(portID, channelID) 729 // check if the portId is already binded, if not bind it 730 _, ok := chain.App().GetScopedIBCKeeper().GetCapability(chain.GetContext(), capName) 731 if !ok { 732 cap, err := chain.App().GetScopedIBCKeeper().NewCapability(chain.GetContext(), capName) 733 require.NoError(chain.t, err) 734 err = scopedKeeper.ClaimCapability(chain.GetContext(), cap, capName) 735 require.NoError(chain.t, err) 736 } 737 738 chain.App().Commit(abci.RequestCommit{}) 739 740 chain.NextBlock() 741 } 742 743 // GetChannelCapability returns the channel capability for the given portID and channelID. 744 // The capability must exist, otherwise testing will fail. 745 func (chain *TestChain) GetChannelCapability(portID, channelID string) *capabilitytypes.Capability { 746 cap, ok := chain.App().GetScopedIBCKeeper().GetCapability(chain.GetContext(), host.ChannelCapabilityPath(portID, channelID)) 747 require.True(chain.t, ok) 748 749 return cap 750 } 751 752 // implement 753 func (chain *TestChain) T() *testing.T { 754 return chain.t 755 } 756 func (chain *TestChain) App() TestingApp { 757 return chain.GetSimApp() 758 } 759 760 func (chain *TestChain) GetContextPointer() *sdk.Context { 761 return &chain.context 762 } 763 764 // func (chain *TestChain) QueryProof(key []byte) ([]byte, clienttypes.Height) {} 765 // func (chain *TestChain) GetConsensusState(clientID string, height exported.Height) (exported.ConsensusState, bool) { 766 // } 767 // func (chain *TestChain) GetPrefix() commitmenttypes.MerklePrefix {} 768 func (chain *TestChain) LastHeader() *ibctmtypes.Header { 769 return chain.lastHeader 770 } 771 func (chain *TestChain) SetLastHeader(lh *ibctmtypes.Header) { 772 chain.lastHeader = lh 773 } 774 775 func (chain *TestChain) QueryServer() types.QueryService { 776 return chain.queryServer 777 } 778 func (chain *TestChain) ChainID() string { 779 return chain.chainID 780 } 781 782 func (chain *TestChain) Codec() *codec.CodecProxy { 783 return chain.codec 784 } 785 func (chain *TestChain) SenderAccount() sdk.Account { 786 return chain.senderAccount 787 } 788 func (chain *TestChain) SenderAccountPV() crypto.PrivKey { 789 790 return chain.senderPrivKey 791 } 792 793 func (chain *TestChain) SenderAccountPVBZ() []byte { 794 return chain.privKeyBz 795 } 796 797 // func (chain *TestChain) CurrentTMClientHeader() *ibctmtypes.Header {} 798 func (chain *TestChain) CurrentHeader() tmproto.Header { 799 return chain.currentHeader 800 } 801 func (chain *TestChain) SetCurrentHeader(h tmproto.Header) { 802 chain.currentHeader = h 803 } 804 805 // func (chain *TestChain) NextBlock() {} 806 // 807 // func CreateTMClientHeader(chainID string, blockHeight int64, trustedHeight clienttypes.Height, timestamp time.Time, tmValSet, tmTrustedVals *tmtypes.ValidatorSet, signers []tmtypes.PrivValidator) *ibctmtypes.Header { 808 // } 809 func (chain *TestChain) Vals() *tmtypes.ValidatorSet { 810 return chain.vals 811 } 812 813 func (chain *TestChain) Signers() []tmtypes.PrivValidator { 814 return chain.signers 815 } 816 817 // func GetSimApp() *simapp.SimApp {} 818 // func GetChannelCapability(portID, channelID string) *capabilitytypes.Capability {} 819 // func CreateChannelCapability(scopedKeeper capabilitykeeper.ScopedKeeper, portID, channelID string) {} 820 // func SendMsgs(msgs ...sdk.Msg) (*sdk.Result, error) {} 821 // func QueryUpgradeProof(key []byte, height uint64) ([]byte, clienttypes.Height) {} 822 func (chain *TestChain) Coordinator() *Coordinator { 823 return chain.coordinator 824 } 825 826 func (chain *TestChain) CurrentHeaderTime(t time.Time) { 827 chain.currentHeader.Time = t 828 } 829 830 //func QueryProofAtHeight(key []byte, height uint64) ([]byte, clienttypes.Height) {}