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  ////}