github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/ibc-go/modules/core/03-connection/keeper/verify.go (about)

     1  package keeper
     2  
     3  import (
     4  	"math"
     5  
     6  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
     7  	sdkerrors "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/errors"
     8  	clienttypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/02-client/types"
     9  	"github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/exported"
    10  )
    11  
    12  // VerifyClientState verifies a proof of a client state of the running machine
    13  // stored on the target machine
    14  func (k Keeper) VerifyClientState(
    15  	ctx sdk.Context,
    16  	connection exported.ConnectionI,
    17  	height exported.Height,
    18  	proof []byte,
    19  	clientState exported.ClientState,
    20  ) error {
    21  	clientID := connection.GetClientID()
    22  	clientStore := k.clientKeeper.ClientStore(ctx, clientID)
    23  
    24  	targetClient, found := k.clientKeeper.GetClientState(ctx, clientID)
    25  	if !found {
    26  		return sdkerrors.Wrap(clienttypes.ErrClientNotFound, clientID)
    27  	}
    28  
    29  	if status := targetClient.Status(ctx, clientStore, k.cdc); status != exported.Active {
    30  		return sdkerrors.Wrapf(clienttypes.ErrClientNotActive, "client (%s) status is %s", clientID, status)
    31  	}
    32  
    33  	if err := targetClient.VerifyClientState(
    34  		clientStore, k.cdc, height,
    35  		connection.GetCounterparty().GetPrefix(), connection.GetCounterparty().GetClientID(), proof, clientState); err != nil {
    36  		return sdkerrors.Wrapf(err, "failed client state verification for target client: %s", clientID)
    37  	}
    38  
    39  	return nil
    40  }
    41  
    42  // VerifyClientConsensusState verifies a proof of the consensus state of the
    43  // specified client stored on the target machine.
    44  func (k Keeper) VerifyClientConsensusState(
    45  	ctx sdk.Context,
    46  	connection exported.ConnectionI,
    47  	height exported.Height,
    48  	consensusHeight exported.Height,
    49  	proof []byte,
    50  	consensusState exported.ConsensusState,
    51  ) error {
    52  	clientID := connection.GetClientID()
    53  	clientStore := k.clientKeeper.ClientStore(ctx, clientID)
    54  
    55  	clientState, found := k.clientKeeper.GetClientState(ctx, clientID)
    56  	if !found {
    57  		return sdkerrors.Wrap(clienttypes.ErrClientNotFound, clientID)
    58  	}
    59  
    60  	if status := clientState.Status(ctx, clientStore, k.cdc); status != exported.Active {
    61  		return sdkerrors.Wrapf(clienttypes.ErrClientNotActive, "client (%s) status is %s", clientID, status)
    62  	}
    63  
    64  	if err := clientState.VerifyClientConsensusState(
    65  		clientStore, k.cdc, height,
    66  		connection.GetCounterparty().GetClientID(), consensusHeight, connection.GetCounterparty().GetPrefix(), proof, consensusState,
    67  	); err != nil {
    68  		return sdkerrors.Wrapf(err, "failed consensus state verification for client (%s)", clientID)
    69  	}
    70  
    71  	return nil
    72  }
    73  
    74  // VerifyConnectionState verifies a proof of the connection state of the
    75  // specified connection end stored on the target machine.
    76  func (k Keeper) VerifyConnectionState(
    77  	ctx sdk.Context,
    78  	connection exported.ConnectionI,
    79  	height exported.Height,
    80  	proof []byte,
    81  	connectionID string,
    82  	connectionEnd exported.ConnectionI, // opposite connection
    83  ) error {
    84  	clientID := connection.GetClientID()
    85  	clientStore := k.clientKeeper.ClientStore(ctx, clientID)
    86  
    87  	clientState, found := k.clientKeeper.GetClientState(ctx, clientID)
    88  	if !found {
    89  		return sdkerrors.Wrap(clienttypes.ErrClientNotFound, clientID)
    90  	}
    91  
    92  	if status := clientState.Status(ctx, clientStore, k.cdc); status != exported.Active {
    93  		return sdkerrors.Wrapf(clienttypes.ErrClientNotActive, "client (%s) status is %s", clientID, status)
    94  	}
    95  
    96  	if err := clientState.VerifyConnectionState(
    97  		clientStore, k.cdc, height,
    98  		connection.GetCounterparty().GetPrefix(), proof, connectionID, connectionEnd,
    99  	); err != nil {
   100  		return sdkerrors.Wrapf(err, "failed connection state verification for client (%s)", clientID)
   101  	}
   102  
   103  	return nil
   104  }
   105  
   106  // VerifyChannelState verifies a proof of the channel state of the specified
   107  // channel end, under the specified port, stored on the target machine.
   108  func (k Keeper) VerifyChannelState(
   109  	ctx sdk.Context,
   110  	connection exported.ConnectionI,
   111  	height exported.Height,
   112  	proof []byte,
   113  	portID,
   114  	channelID string,
   115  	channel exported.ChannelI,
   116  ) error {
   117  	clientID := connection.GetClientID()
   118  	clientStore := k.clientKeeper.ClientStore(ctx, clientID)
   119  
   120  	clientState, found := k.clientKeeper.GetClientState(ctx, clientID)
   121  	if !found {
   122  		return sdkerrors.Wrap(clienttypes.ErrClientNotFound, clientID)
   123  	}
   124  
   125  	if status := clientState.Status(ctx, clientStore, k.cdc); status != exported.Active {
   126  		return sdkerrors.Wrapf(clienttypes.ErrClientNotActive, "client (%s) status is %s", clientID, status)
   127  	}
   128  
   129  	if err := clientState.VerifyChannelState(
   130  		clientStore, k.cdc, height,
   131  		connection.GetCounterparty().GetPrefix(), proof,
   132  		portID, channelID, channel,
   133  	); err != nil {
   134  		return sdkerrors.Wrapf(err, "failed channel state verification for client (%s)", clientID)
   135  	}
   136  
   137  	return nil
   138  }
   139  
   140  // VerifyPacketCommitment verifies a proof of an outgoing packet commitment at
   141  // the specified port, specified channel, and specified sequence.
   142  func (k Keeper) VerifyPacketCommitment(
   143  	ctx sdk.Context,
   144  	connection exported.ConnectionI,
   145  	height exported.Height,
   146  	proof []byte,
   147  	portID,
   148  	channelID string,
   149  	sequence uint64,
   150  	commitmentBytes []byte,
   151  ) error {
   152  	clientID := connection.GetClientID()
   153  	clientStore := k.clientKeeper.ClientStore(ctx, clientID)
   154  
   155  	clientState, found := k.clientKeeper.GetClientState(ctx, clientID)
   156  	if !found {
   157  		return sdkerrors.Wrap(clienttypes.ErrClientNotFound, clientID)
   158  	}
   159  
   160  	if status := clientState.Status(ctx, clientStore, k.cdc); status != exported.Active {
   161  		return sdkerrors.Wrapf(clienttypes.ErrClientNotActive, "client (%s) status is %s", clientID, status)
   162  	}
   163  
   164  	// get time and block delays
   165  	timeDelay := connection.GetDelayPeriod()
   166  	blockDelay := k.getBlockDelay(ctx, connection)
   167  
   168  	if err := clientState.VerifyPacketCommitment(
   169  		ctx, clientStore, k.cdc, height,
   170  		timeDelay, blockDelay,
   171  		connection.GetCounterparty().GetPrefix(), proof, portID, channelID,
   172  		sequence, commitmentBytes,
   173  	); err != nil {
   174  		return sdkerrors.Wrapf(err, "failed packet commitment verification for client (%s)", clientID)
   175  	}
   176  
   177  	return nil
   178  }
   179  
   180  // VerifyPacketAcknowledgement verifies a proof of an incoming packet
   181  // acknowledgement at the specified port, specified channel, and specified sequence.
   182  func (k Keeper) VerifyPacketAcknowledgement(
   183  	ctx sdk.Context,
   184  	connection exported.ConnectionI,
   185  	height exported.Height,
   186  	proof []byte,
   187  	portID,
   188  	channelID string,
   189  	sequence uint64,
   190  	acknowledgement []byte,
   191  ) error {
   192  	clientID := connection.GetClientID()
   193  	clientStore := k.clientKeeper.ClientStore(ctx, clientID)
   194  
   195  	clientState, found := k.clientKeeper.GetClientState(ctx, clientID)
   196  	if !found {
   197  		return sdkerrors.Wrap(clienttypes.ErrClientNotFound, clientID)
   198  	}
   199  
   200  	if status := clientState.Status(ctx, clientStore, k.cdc); status != exported.Active {
   201  		return sdkerrors.Wrapf(clienttypes.ErrClientNotActive, "client (%s) status is %s", clientID, status)
   202  	}
   203  
   204  	// get time and block delays
   205  	timeDelay := connection.GetDelayPeriod()
   206  	blockDelay := k.getBlockDelay(ctx, connection)
   207  
   208  	if err := clientState.VerifyPacketAcknowledgement(
   209  		ctx, clientStore, k.cdc, height,
   210  		timeDelay, blockDelay,
   211  		connection.GetCounterparty().GetPrefix(), proof, portID, channelID,
   212  		sequence, acknowledgement,
   213  	); err != nil {
   214  		return sdkerrors.Wrapf(err, "failed packet acknowledgement verification for client (%s)", clientID)
   215  	}
   216  
   217  	return nil
   218  }
   219  
   220  // VerifyPacketReceiptAbsence verifies a proof of the absence of an
   221  // incoming packet receipt at the specified port, specified channel, and
   222  // specified sequence.
   223  func (k Keeper) VerifyPacketReceiptAbsence(
   224  	ctx sdk.Context,
   225  	connection exported.ConnectionI,
   226  	height exported.Height,
   227  	proof []byte,
   228  	portID,
   229  	channelID string,
   230  	sequence uint64,
   231  ) error {
   232  	clientID := connection.GetClientID()
   233  	clientStore := k.clientKeeper.ClientStore(ctx, clientID)
   234  
   235  	clientState, found := k.clientKeeper.GetClientState(ctx, clientID)
   236  	if !found {
   237  		return sdkerrors.Wrap(clienttypes.ErrClientNotFound, clientID)
   238  	}
   239  
   240  	if status := clientState.Status(ctx, clientStore, k.cdc); status != exported.Active {
   241  		return sdkerrors.Wrapf(clienttypes.ErrClientNotActive, "client (%s) status is %s", clientID, status)
   242  	}
   243  
   244  	// get time and block delays
   245  	timeDelay := connection.GetDelayPeriod()
   246  	blockDelay := k.getBlockDelay(ctx, connection)
   247  
   248  	if err := clientState.VerifyPacketReceiptAbsence(
   249  		ctx, clientStore, k.cdc, height,
   250  		timeDelay, blockDelay,
   251  		connection.GetCounterparty().GetPrefix(), proof, portID, channelID,
   252  		sequence,
   253  	); err != nil {
   254  		return sdkerrors.Wrapf(err, "failed packet receipt absence verification for client (%s)", clientID)
   255  	}
   256  
   257  	return nil
   258  }
   259  
   260  // VerifyNextSequenceRecv verifies a proof of the next sequence number to be
   261  // received of the specified channel at the specified port.
   262  func (k Keeper) VerifyNextSequenceRecv(
   263  	ctx sdk.Context,
   264  	connection exported.ConnectionI,
   265  	height exported.Height,
   266  	proof []byte,
   267  	portID,
   268  	channelID string,
   269  	nextSequenceRecv uint64,
   270  ) error {
   271  	clientID := connection.GetClientID()
   272  	clientStore := k.clientKeeper.ClientStore(ctx, clientID)
   273  
   274  	clientState, found := k.clientKeeper.GetClientState(ctx, clientID)
   275  	if !found {
   276  		return sdkerrors.Wrap(clienttypes.ErrClientNotFound, clientID)
   277  	}
   278  
   279  	if status := clientState.Status(ctx, clientStore, k.cdc); status != exported.Active {
   280  		return sdkerrors.Wrapf(clienttypes.ErrClientNotActive, "client (%s) status is %s", clientID, status)
   281  	}
   282  
   283  	// get time and block delays
   284  	timeDelay := connection.GetDelayPeriod()
   285  	blockDelay := k.getBlockDelay(ctx, connection)
   286  
   287  	if err := clientState.VerifyNextSequenceRecv(
   288  		ctx, clientStore, k.cdc, height,
   289  		timeDelay, blockDelay,
   290  		connection.GetCounterparty().GetPrefix(), proof, portID, channelID,
   291  		nextSequenceRecv,
   292  	); err != nil {
   293  		return sdkerrors.Wrapf(err, "failed next sequence receive verification for client (%s)", clientID)
   294  	}
   295  
   296  	return nil
   297  }
   298  
   299  // getBlockDelay calculates the block delay period from the time delay of the connection
   300  // and the maximum expected time per block.
   301  func (k Keeper) getBlockDelay(ctx sdk.Context, connection exported.ConnectionI) uint64 {
   302  	// expectedTimePerBlock should never be zero, however if it is then return a 0 blcok delay for safety
   303  	// as the expectedTimePerBlock parameter was not set.
   304  	expectedTimePerBlock := k.GetMaxExpectedTimePerBlock(ctx)
   305  	if expectedTimePerBlock == 0 {
   306  		return 0
   307  	}
   308  	// calculate minimum block delay by dividing time delay period
   309  	// by the expected time per block. Round up the block delay.
   310  	timeDelay := connection.GetDelayPeriod()
   311  	return uint64(math.Ceil(float64(timeDelay) / float64(expectedTimePerBlock)))
   312  }