Some checks failed
CodeQL / Analyze (push) Waiting to run
golangci-lint / lint (push) Waiting to run
Tests / Code Coverage / build (amd64) (push) Waiting to run
Tests / Code Coverage / build (arm64) (push) Waiting to run
Tests / Code Coverage / unit-tests (map[additional-args:-tags="test_e2e" name:e2e path:./e2e]) (push) Waiting to run
Tests / Code Coverage / unit-tests (map[name:08-wasm path:./modules/light-clients/08-wasm]) (push) Waiting to run
Tests / Code Coverage / unit-tests (map[name:ibc-go path:.]) (push) Waiting to run
Docker Build & Push Simapp (main) / docker-build (push) Has been cancelled
245 lines
7 KiB
Go
245 lines
7 KiB
Go
package ibctesting
|
|
|
|
import (
|
|
"bytes"
|
|
"errors"
|
|
|
|
abci "git.cw.tr/mukan-network/mukan-consensus/abci/types"
|
|
|
|
transfertypes "git.cw.tr/mukan-network/mukan-ibc/modules/apps/transfer/types"
|
|
channeltypes "git.cw.tr/mukan-network/mukan-ibc/modules/core/04-channel/types"
|
|
)
|
|
|
|
// Path contains two endpoints representing two chains connected over IBC
|
|
type Path struct {
|
|
EndpointA *Endpoint
|
|
EndpointB *Endpoint
|
|
}
|
|
|
|
// NewPath constructs an endpoint for each chain using the default values
|
|
// for the endpoints. Each endpoint is updated to have a pointer to the
|
|
// counterparty endpoint.
|
|
func NewPath(chainA, chainB *TestChain) *Path {
|
|
endpointA := NewDefaultEndpoint(chainA)
|
|
endpointB := NewDefaultEndpoint(chainB)
|
|
|
|
endpointA.Counterparty = endpointB
|
|
endpointB.Counterparty = endpointA
|
|
|
|
return &Path{
|
|
EndpointA: endpointA,
|
|
EndpointB: endpointB,
|
|
}
|
|
}
|
|
|
|
// NewTransferPath constructs a new path between each chain suitable for use with
|
|
// the transfer module.
|
|
func NewTransferPath(chainA, chainB *TestChain) *Path {
|
|
path := NewPath(chainA, chainB)
|
|
path.EndpointA.ChannelConfig.PortID = TransferPort
|
|
path.EndpointB.ChannelConfig.PortID = TransferPort
|
|
path.EndpointA.ChannelConfig.Version = transfertypes.V1
|
|
path.EndpointB.ChannelConfig.Version = transfertypes.V1
|
|
|
|
return path
|
|
}
|
|
|
|
// SetChannelOrdered sets the channel order for both endpoints to ORDERED.
|
|
func (path *Path) SetChannelOrdered() {
|
|
path.EndpointA.ChannelConfig.Order = channeltypes.ORDERED
|
|
path.EndpointB.ChannelConfig.Order = channeltypes.ORDERED
|
|
}
|
|
|
|
// DisableUniqueChannelIDs provides an opt-out way to not have all channel IDs be different
|
|
// while testing.
|
|
func (path *Path) DisableUniqueChannelIDs() *Path {
|
|
path.EndpointA.disableUniqueChannelIDs = true
|
|
path.EndpointB.disableUniqueChannelIDs = true
|
|
return path
|
|
}
|
|
|
|
// RelayPacket attempts to relay the packet first on EndpointA and then on EndpointB
|
|
// if EndpointA does not contain a packet commitment for that packet. An error is returned
|
|
// if a relay step fails or the packet commitment does not exist on either endpoint.
|
|
func (path *Path) RelayPacket(packet channeltypes.Packet) error {
|
|
_, _, err := path.RelayPacketWithResults(packet)
|
|
return err
|
|
}
|
|
|
|
// RelayPacketWithResults attempts to relay the packet first on EndpointA and then on EndpointB
|
|
// if EndpointA does not contain a packet commitment for that packet. The function returns:
|
|
// - The result of the packet receive transaction.
|
|
// - The acknowledgement written on the receiving chain.
|
|
// - An error if a relay step fails or the packet commitment does not exist on either endpoint.
|
|
func (path *Path) RelayPacketWithResults(packet channeltypes.Packet) (*abci.ExecTxResult, []byte, error) {
|
|
pc := path.EndpointA.Chain.App.GetIBCKeeper().ChannelKeeper.GetPacketCommitment(path.EndpointA.Chain.GetContext(), packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence())
|
|
if bytes.Equal(pc, channeltypes.CommitPacket(packet)) {
|
|
// packet found, relay from A to B
|
|
if err := path.EndpointB.UpdateClient(); err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
res, err := path.EndpointB.RecvPacketWithResult(packet)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
ack, err := ParseAckFromEvents(res.Events)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
if err := path.EndpointA.AcknowledgePacket(packet, ack); err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
return res, ack, nil
|
|
}
|
|
|
|
pc = path.EndpointB.Chain.App.GetIBCKeeper().ChannelKeeper.GetPacketCommitment(path.EndpointB.Chain.GetContext(), packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence())
|
|
if bytes.Equal(pc, channeltypes.CommitPacket(packet)) {
|
|
// packet found, relay B to A
|
|
if err := path.EndpointA.UpdateClient(); err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
res, err := path.EndpointA.RecvPacketWithResult(packet)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
ack, err := ParseAckFromEvents(res.Events)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
if err := path.EndpointB.AcknowledgePacket(packet, ack); err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
return res, ack, nil
|
|
}
|
|
|
|
return nil, nil, errors.New("packet commitment does not exist on either endpoint for provided packet")
|
|
}
|
|
|
|
// Reversed returns a new path with endpoints reversed.
|
|
func (path *Path) Reversed() *Path {
|
|
reversedPath := *path
|
|
reversedPath.EndpointA, reversedPath.EndpointB = path.EndpointB, path.EndpointA
|
|
return &reversedPath
|
|
}
|
|
|
|
// Setup constructs a TM client, connection, and channel on both chains provided. It will
|
|
// fail if any error occurs.
|
|
func (path *Path) Setup() {
|
|
path.SetupConnections()
|
|
|
|
// channels can also be referenced through the returned connections
|
|
path.CreateChannels()
|
|
}
|
|
|
|
// SetupV2 constructs clients on both sides and then provides the counterparties for both sides
|
|
// This is all that is necessary for path setup with the IBC v2 protocol
|
|
func (path *Path) SetupV2() {
|
|
path.SetupClients()
|
|
|
|
path.SetupCounterparties()
|
|
}
|
|
|
|
// SetupClients is a helper function to create clients on both chains. It assumes the
|
|
// caller does not anticipate any errors.
|
|
func (path *Path) SetupClients() {
|
|
err := path.EndpointA.CreateClient()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
err = path.EndpointB.CreateClient()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
// SetupCounterparties is a helper function to set the counterparties supporting IBC v2 on both
|
|
// chains. It assumes the caller does not anticipate any errors.
|
|
func (path *Path) SetupCounterparties() {
|
|
if err := path.EndpointB.RegisterCounterparty(); err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
if err := path.EndpointA.RegisterCounterparty(); err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
// SetupConnections is a helper function to create clients and the appropriate
|
|
// connections on both the source and counterparty chain. It assumes the caller does not
|
|
// anticipate any errors.
|
|
func (path *Path) SetupConnections() {
|
|
path.SetupClients()
|
|
|
|
path.CreateConnections()
|
|
}
|
|
|
|
// CreateConnections constructs and executes connection handshake messages in order to create
|
|
// OPEN connections on chainA and chainB. The function expects the connections to be
|
|
// successfully opened otherwise testing will fail.
|
|
func (path *Path) CreateConnections() {
|
|
err := path.EndpointA.ConnOpenInit()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
err = path.EndpointB.ConnOpenTry()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
err = path.EndpointA.ConnOpenAck()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
err = path.EndpointB.ConnOpenConfirm()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
// ensure counterparty is up to date
|
|
err = path.EndpointA.UpdateClient()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
// CreateChannels constructs and executes channel handshake messages in order to create
|
|
// OPEN channels on chainA and chainB. The function expects the channels to be successfully
|
|
// opened otherwise testing will fail.
|
|
func (path *Path) CreateChannels() {
|
|
err := path.EndpointA.ChanOpenInit()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
err = path.EndpointB.ChanOpenTry()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
err = path.EndpointA.ChanOpenAck()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
err = path.EndpointB.ChanOpenConfirm()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
// ensure counterparty is up to date
|
|
err = path.EndpointA.UpdateClient()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
}
|