github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/wasm/ibctesting/coordinator.go (about) 1 package ibctesting 2 3 //import ( 4 // "fmt" 5 // "strconv" 6 // "testing" 7 // "time" 8 // 9 // channeltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types" 10 // host "github.com/cosmos/ibc-go/v3/modules/core/24-host" 11 // ibctesting "github.com/cosmos/ibc-go/v3/testing" 12 // "github.com/stretchr/testify/require" 13 // abci "github.com/tendermint/tendermint/abci/types" 14 // 15 // wasmkeeper "github.com/fibonacci-chain/fbc/x/wasm/keeper" 16 //) 17 // 18 //const ChainIDPrefix = "testchain" 19 // 20 //var ( 21 // globalStartTime = time.Date(2020, 12, 4, 10, 30, 0, 0, time.UTC) 22 // TimeIncrement = time.Second * 5 23 //) 24 // 25 //// Coordinator is a testing struct which contains N TestChain's. It handles keeping all chains 26 //// in sync with regards to time. 27 //type Coordinator struct { 28 // t *testing.T 29 // 30 // CurrentTime time.Time 31 // Chains map[string]*TestChain 32 //} 33 // 34 //// NewCoordinator initializes Coordinator with N TestChain's 35 //func NewCoordinator(t *testing.T, n int, opts ...[]wasmkeeper.Option) *Coordinator { 36 // chains := make(map[string]*TestChain) 37 // coord := &Coordinator{ 38 // t: t, 39 // CurrentTime: globalStartTime, 40 // } 41 // 42 // for i := 0; i < n; i++ { 43 // chainID := GetChainID(i) 44 // var x []wasmkeeper.Option 45 // if len(opts) > i { 46 // x = opts[i] 47 // } 48 // chains[chainID] = NewTestChain(t, coord, chainID, x...) 49 // } 50 // coord.Chains = chains 51 // 52 // return coord 53 //} 54 // 55 //// IncrementTime iterates through all the TestChain's and increments their current header time 56 //// by 5 seconds. 57 //// 58 //// CONTRACT: this function must be called after every Commit on any TestChain. 59 //func (coord *Coordinator) IncrementTime() { 60 // coord.IncrementTimeBy(TimeIncrement) 61 //} 62 // 63 //// IncrementTimeBy iterates through all the TestChain's and increments their current header time 64 //// by specified time. 65 //func (coord *Coordinator) IncrementTimeBy(increment time.Duration) { 66 // coord.CurrentTime = coord.CurrentTime.Add(increment).UTC() 67 // coord.UpdateTime() 68 //} 69 // 70 //// UpdateTime updates all clocks for the TestChains to the current global time. 71 //func (coord *Coordinator) UpdateTime() { 72 // for _, chain := range coord.Chains { 73 // coord.UpdateTimeForChain(chain) 74 // } 75 //} 76 // 77 //// UpdateTimeForChain updates the clock for a specific chain. 78 //func (coord *Coordinator) UpdateTimeForChain(chain *TestChain) { 79 // chain.CurrentHeader.Time = coord.CurrentTime.UTC() 80 // chain.App.BeginBlock(abci.RequestBeginBlock{Header: chain.CurrentHeader}) 81 //} 82 // 83 //// Setup constructs a TM client, connection, and channel on both chains provided. It will 84 //// fail if any error occurs. The clientID's, TestConnections, and TestChannels are returned 85 //// for both chains. The channels created are connected to the ibc-transfer application. 86 //func (coord *Coordinator) Setup(path *Path) { 87 // coord.SetupConnections(path) 88 // 89 // // channels can also be referenced through the returned connections 90 // coord.CreateChannels(path) 91 //} 92 // 93 //// SetupClients is a helper function to create clients on both chains. It assumes the 94 //// caller does not anticipate any errors. 95 //func (coord *Coordinator) SetupClients(path *Path) { 96 // err := path.EndpointA.CreateClient() 97 // require.NoError(coord.t, err) 98 // 99 // err = path.EndpointB.CreateClient() 100 // require.NoError(coord.t, err) 101 //} 102 // 103 //// SetupClientConnections is a helper function to create clients and the appropriate 104 //// connections on both the source and counterparty chain. It assumes the caller does not 105 //// anticipate any errors. 106 //func (coord *Coordinator) SetupConnections(path *Path) { 107 // coord.SetupClients(path) 108 // 109 // coord.CreateConnections(path) 110 //} 111 // 112 //// CreateConnection constructs and executes connection handshake messages in order to create 113 //// OPEN channels on chainA and chainB. The connection information of for chainA and chainB 114 //// are returned within a TestConnection struct. The function expects the connections to be 115 //// successfully opened otherwise testing will fail. 116 //func (coord *Coordinator) CreateConnections(path *Path) { 117 // err := path.EndpointA.ConnOpenInit() 118 // require.NoError(coord.t, err) 119 // 120 // err = path.EndpointB.ConnOpenTry() 121 // require.NoError(coord.t, err) 122 // 123 // err = path.EndpointA.ConnOpenAck() 124 // require.NoError(coord.t, err) 125 // 126 // err = path.EndpointB.ConnOpenConfirm() 127 // require.NoError(coord.t, err) 128 // 129 // // ensure counterparty is up to date 130 // err = path.EndpointA.UpdateClient() 131 // require.NoError(coord.t, err) 132 //} 133 // 134 //// CreateMockChannels constructs and executes channel handshake messages to create OPEN 135 //// channels that use a mock application module that returns nil on all callbacks. This 136 //// function is expects the channels to be successfully opened otherwise testing will 137 //// fail. 138 //func (coord *Coordinator) CreateMockChannels(path *Path) { 139 // path.EndpointA.ChannelConfig.PortID = ibctesting.MockPort 140 // path.EndpointB.ChannelConfig.PortID = ibctesting.MockPort 141 // 142 // coord.CreateChannels(path) 143 //} 144 // 145 //// CreateTransferChannels constructs and executes channel handshake messages to create OPEN 146 //// ibc-transfer channels on chainA and chainB. The function expects the channels to be 147 //// successfully opened otherwise testing will fail. 148 //func (coord *Coordinator) CreateTransferChannels(path *Path) { 149 // path.EndpointA.ChannelConfig.PortID = ibctesting.TransferPort 150 // path.EndpointB.ChannelConfig.PortID = ibctesting.TransferPort 151 // 152 // coord.CreateChannels(path) 153 //} 154 // 155 //// CreateChannel constructs and executes channel handshake messages in order to create 156 //// OPEN channels on chainA and chainB. The function expects the channels to be successfully 157 //// opened otherwise testing will fail. 158 //func (coord *Coordinator) CreateChannels(path *Path) { 159 // err := path.EndpointA.ChanOpenInit() 160 // require.NoError(coord.t, err) 161 // 162 // err = path.EndpointB.ChanOpenTry() 163 // require.NoError(coord.t, err) 164 // 165 // err = path.EndpointA.ChanOpenAck() 166 // require.NoError(coord.t, err) 167 // 168 // err = path.EndpointB.ChanOpenConfirm() 169 // require.NoError(coord.t, err) 170 // 171 // // ensure counterparty is up to date 172 // err = path.EndpointA.UpdateClient() 173 // require.NoError(coord.t, err) 174 //} 175 // 176 //// GetChain returns the TestChain using the given chainID and returns an error if it does 177 //// not exist. 178 //func (coord *Coordinator) GetChain(chainID string) *TestChain { 179 // chain, found := coord.Chains[chainID] 180 // require.True(coord.t, found, fmt.Sprintf("%s chain does not exist", chainID)) 181 // return chain 182 //} 183 // 184 //// GetChainID returns the chainID used for the provided index. 185 //func GetChainID(index int) string { 186 // return ChainIDPrefix + strconv.Itoa(index) 187 //} 188 // 189 //// CommitBlock commits a block on the provided indexes and then increments the global time. 190 ////// 191 ////// CONTRACT: the passed in list of indexes must not contain duplicates 192 ////func (coord *Coordinator) CommitBlock(chains ...*TestChain) { 193 //// for _, chain := range chains { 194 //// chain.App.Commit() 195 //// chain.NextBlock() 196 //// } 197 //// coord.IncrementTime() 198 ////} 199 //// 200 ////// CommitNBlocks commits n blocks to state and updates the block height by 1 for each commit. 201 ////func (coord *Coordinator) CommitNBlocks(chain *TestChain, n uint64) { 202 //// for i := uint64(0); i < n; i++ { 203 //// chain.App.BeginBlock(abci.RequestBeginBlock{Header: chain.CurrentHeader}) 204 //// chain.App.Commit() 205 //// chain.NextBlock() 206 //// coord.IncrementTime() 207 //// } 208 ////} 209 //// 210 ////// ConnOpenInitOnBothChains initializes a connection on both endpoints with the state INIT 211 ////// using the OpenInit handshake call. 212 ////func (coord *Coordinator) ConnOpenInitOnBothChains(path *Path) error { 213 //// if err := path.EndpointA.ConnOpenInit(); err != nil { 214 //// return err 215 //// } 216 //// 217 //// if err := path.EndpointB.ConnOpenInit(); err != nil { 218 //// return err 219 //// } 220 //// 221 //// if err := path.EndpointA.UpdateClient(); err != nil { 222 //// return err 223 //// } 224 //// 225 //// if err := path.EndpointB.UpdateClient(); err != nil { 226 //// return err 227 //// } 228 //// 229 //// return nil 230 ////} 231 //// 232 ////// ChanOpenInitOnBothChains initializes a channel on the source chain and counterparty chain 233 ////// with the state INIT using the OpenInit handshake call. 234 ////func (coord *Coordinator) ChanOpenInitOnBothChains(path *Path) error { 235 //// // NOTE: only creation of a capability for a transfer or mock port is supported 236 //// // Other applications must bind to the port in InitGenesis or modify this code. 237 //// 238 //// if err := path.EndpointA.ChanOpenInit(); err != nil { 239 //// return err 240 //// } 241 //// 242 //// if err := path.EndpointB.ChanOpenInit(); err != nil { 243 //// return err 244 //// } 245 //// 246 //// if err := path.EndpointA.UpdateClient(); err != nil { 247 //// return err 248 //// } 249 //// 250 //// if err := path.EndpointB.UpdateClient(); err != nil { 251 //// return err 252 //// } 253 //// 254 //// return nil 255 ////} 256 //// 257 ////// from A to B 258 ////func (coord *Coordinator) RelayAndAckPendingPackets(path *Path) error { 259 //// // get all the packet to relay src->dest 260 //// src := path.EndpointA 261 //// dest := path.EndpointB 262 //// toSend := src.Chain.PendingSendPackets 263 //// coord.t.Logf("Relay %d Packets A->B\n", len(toSend)) 264 //// 265 //// // send this to the other side 266 //// coord.IncrementTime() 267 //// coord.CommitBlock(src.Chain) 268 //// err := dest.UpdateClient() 269 //// if err != nil { 270 //// return err 271 //// } 272 //// for _, packet := range toSend { 273 //// err = dest.RecvPacket(packet) 274 //// if err != nil { 275 //// return err 276 //// } 277 //// } 278 //// src.Chain.PendingSendPackets = nil 279 //// 280 //// // get all the acks to relay dest->src 281 //// toAck := dest.Chain.PendingAckPackets 282 //// // TODO: assert >= len(toSend)? 283 //// coord.t.Logf("Ack %d Packets B->A\n", len(toAck)) 284 //// 285 //// // send the ack back from dest -> src 286 //// coord.IncrementTime() 287 //// coord.CommitBlock(dest.Chain) 288 //// err = src.UpdateClient() 289 //// if err != nil { 290 //// return err 291 //// } 292 //// for _, ack := range toAck { 293 //// err = src.AcknowledgePacket(ack.Packet, ack.Ack) 294 //// if err != nil { 295 //// return err 296 //// } 297 //// } 298 //// dest.Chain.PendingAckPackets = nil 299 //// return nil 300 ////} 301 //// 302 ////// TimeoutPendingPackets returns the package to source chain to let the IBC app revert any operation. 303 ////// from A to A 304 ////func (coord *Coordinator) TimeoutPendingPackets(path *Path) error { 305 //// src := path.EndpointA 306 //// dest := path.EndpointB 307 //// 308 //// toSend := src.Chain.PendingSendPackets 309 //// coord.t.Logf("Timeout %d Packets A->A\n", len(toSend)) 310 //// 311 //// if err := src.UpdateClient(); err != nil { 312 //// return err 313 //// } 314 //// // Increment time and commit block so that 5 second delay period passes between send and receive 315 //// coord.IncrementTime() 316 //// coord.CommitBlock(src.Chain, dest.Chain) 317 //// for _, packet := range toSend { 318 //// // get proof of packet unreceived on dest 319 //// packetKey := host.PacketReceiptKey(packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence()) 320 //// proofUnreceived, proofHeight := dest.QueryProof(packetKey) 321 //// timeoutMsg := channeltypes.NewMsgTimeout(packet, packet.Sequence, proofUnreceived, proofHeight, src.Chain.SenderAccount.GetAddress().String()) 322 //// err := src.Chain.sendMsgs(timeoutMsg) 323 //// if err != nil { 324 //// return err 325 //// } 326 //// } 327 //// src.Chain.PendingSendPackets = nil 328 //// dest.Chain.PendingAckPackets = nil 329 //// return nil 330 ////} 331 //// 332 ////// CloseChannel close channel on both sides 333 ////func (coord *Coordinator) CloseChannel(path *Path) { 334 //// err := path.EndpointA.ChanCloseInit() 335 //// require.NoError(coord.t, err) 336 //// coord.IncrementTime() 337 //// err = path.EndpointB.UpdateClient() 338 //// require.NoError(coord.t, err) 339 //// err = path.EndpointB.ChanCloseConfirm() 340 //// require.NoError(coord.t, err) 341 ////}