Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP][IBC] Implement ICS-02 Client Semantics #916

Draft
wants to merge 23 commits into
base: ibc/proto-exploration-ics23
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Implement UpdateClient method
  • Loading branch information
h5law committed Jul 24, 2023
commit 04d969d797ae3baba7e8efbaecf5eb60766e22e1
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,7 @@ protogen_local: go_protoc-go-inject-tag ## Generate go structures for all of the
# IBC
make copy_ics23_proto
$(PROTOC_SHARED) -I=./ibc/types/proto --go_out=./ibc/types ./ibc/types/proto/*.proto
$(PROTOC_SHARED) -I=./ibc/client/types/proto --go_out=./ibc/client/types ./ibc/client/types/proto/*.proto

# echo "View generated proto files by running: make protogen_show"

Expand Down
6 changes: 3 additions & 3 deletions ibc/client/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func (c *clientManager) emitCreateClientEvent(clientId string, clientState modul
Attributes: []*core_types.Attribute{
core_types.NewAttribute(client_types.AttributeKeyClientID, []byte(clientId)),
core_types.NewAttribute(client_types.AttributeKeyClientType, []byte(clientState.ClientType())),
core_types.NewAttribute(client_types.AttributeKeyConsensusHeight, []byte(clientState.GetLatestHeight().String())),
core_types.NewAttribute(client_types.AttributeKeyConsensusHeight, []byte(clientState.GetLatestHeight().ToString())),
},
},
)
Expand All @@ -39,7 +39,7 @@ func (c *clientManager) emitUpdateClientEvent(
Attributes: []*core_types.Attribute{
core_types.NewAttribute(client_types.AttributeKeyClientID, []byte(clientId)),
core_types.NewAttribute(client_types.AttributeKeyClientType, []byte(clientType)),
core_types.NewAttribute(client_types.AttributeKeyConsensusHeight, []byte(consensusHeight.String())),
core_types.NewAttribute(client_types.AttributeKeyConsensusHeight, []byte(consensusHeight.ToString())),
core_types.NewAttribute(client_types.AttributeKeyHeader, clientMsgBz),
},
},
Expand All @@ -54,7 +54,7 @@ func (c *clientManager) emitUpgradeClientEvent(clientId string, clientState modu
Attributes: []*core_types.Attribute{
core_types.NewAttribute(client_types.AttributeKeyClientID, []byte(clientId)),
core_types.NewAttribute(client_types.AttributeKeyClientType, []byte(clientState.ClientType())),
core_types.NewAttribute(client_types.AttributeKeyConsensusHeight, []byte(clientState.GetLatestHeight().String())),
core_types.NewAttribute(client_types.AttributeKeyConsensusHeight, []byte(clientState.GetLatestHeight().ToString())),
},
},
)
Expand Down
56 changes: 56 additions & 0 deletions ibc/client/queries.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package client

import (
"github.com/pokt-network/pocket/ibc/path"
"github.com/pokt-network/pocket/shared/codec"
"github.com/pokt-network/pocket/shared/modules"
)

// GetConsensusState returns the ConsensusState at the given height for the
// stored client with the given identifier
func (c *clientManager) GetConsensusState(
identifier string, height modules.Height,
) (modules.ConsensusState, error) {
// Retrieve the client store
clientStore, err := c.GetBus().GetIBCHost().GetProvableStore(path.KeyClientStorePrefix)
if err != nil {
return nil, err
}

// Retrieve the consensus state bytes from the client store
consStateBz, err := clientStore.Get(path.FullConsensusStateKey(identifier, height.ToString()))
if err != nil {
return nil, err
}

// Unmarshal into a ConsensusState interface
var consState modules.ConsensusState
if err := codec.GetInterfaceRegistry().UnmarshalInterface(consStateBz, &consState); err != nil {
return nil, err
}

return consState, nil
}

// GetClientState returns the ClientState for the stored client with the given identifier
func (c *clientManager) GetClientState(identifier string) (modules.ClientState, error) {
// Retrieve the client store
clientStore, err := c.GetBus().GetIBCHost().GetProvableStore(path.KeyClientStorePrefix)
if err != nil {
return nil, err
}

// Retrieve the client state bytes from the client store
clientStateBz, err := clientStore.Get(path.FullClientStateKey(identifier))
if err != nil {
return nil, err
}

// Unmarshal into a ClientState interface
var clientState modules.ClientState
if err := codec.GetInterfaceRegistry().UnmarshalInterface(clientStateBz, &clientState); err != nil {
return nil, err
}

return clientState, nil
}
60 changes: 47 additions & 13 deletions ibc/client/submodule.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"

"github.com/pokt-network/pocket/ibc/path"
core_types "github.com/pokt-network/pocket/shared/core/types"
"github.com/pokt-network/pocket/shared/modules"
"github.com/pokt-network/pocket/shared/modules/base_modules"
)
Expand Down Expand Up @@ -78,7 +79,7 @@ func (c *clientManager) CreateClient(
return "", err
}

c.logger.Info().Str("identifier", identifier).Str("height", clientState.GetLatestHeight().String()).Msg("client created at height")
c.logger.Info().Str("identifier", identifier).Str("height", clientState.GetLatestHeight().ToString()).Msg("client created at height")

// Emit the create client event to the event logger
if err := c.emitCreateClientEvent(identifier, clientState); err != nil {
Expand All @@ -94,20 +95,53 @@ func (c *clientManager) CreateClient(
func (c *clientManager) UpdateClient(
identifier string, clientMessage modules.ClientMessage,
) error {
return nil
}
// Get the client state
clientState, err := c.GetClientState(identifier)
if err != nil {
return err
}

// QueryConsensusState returns the ConsensusState at the given height for the
// stored client with the given identifier
func (c *clientManager) QueryConsensusState(
identifier string, height modules.Height,
) (modules.ConsensusState, error) {
return nil, nil
}
// Get the client store
clientStore, err := c.GetBus().GetIBCHost().GetProvableStore(path.KeyClientStorePrefix)
if err != nil {
return err
}

// Check the state is active
if clientState.Status(clientStore) != modules.ActiveStatus {
return core_types.ErrIBCClientNotActive()
}

// QueryClientState returns the ClientState for the stored client with the given identifier
func (c *clientManager) QueryClientState(identifier string) (modules.ClientState, error) {
return nil, nil
// Verify the client message
if err := clientState.VerifyClientMessage(clientStore, clientMessage); err != nil {
return err
}

// Check for misbehaviour on the source chain
misbehaved := clientState.CheckForMisbehaviour(clientStore, clientMessage)
if misbehaved {
clientState.UpdateStateOnMisbehaviour(clientStore, clientMessage)
c.logger.Info().Str("identifier", identifier).Msg("client frozen for misbehaviour")

// emit the submit misbehaviour event to the event logger
if err := c.emitSubmitMisbehaviourEvent(identifier, clientState); err != nil {
c.logger.Error().Err(err).Str("identifier", identifier).Msg("failed to emit client submit misbehaviour event")
return err
}
return nil
}

// Update the client
consensusHeight := clientState.UpdateState(clientStore, clientMessage)
c.logger.Info().Str("identifier", identifier).Str("height", consensusHeight.ToString()).Msg("client state updated")

// emit the update client event to the event logger
if err := c.emitUpdateClientEvent(identifier, clientState.ClientType(), consensusHeight, clientMessage); err != nil {
c.logger.Error().Err(err).Str("identifier", identifier).Msg("failed to emit client update event")
return err
}

return nil
}

// SubmitMisbehaviour submits evidence for a misbehaviour to the client, possibly
Expand Down
4 changes: 3 additions & 1 deletion ibc/path/keys_ics02.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package path

import "fmt"
import (
"fmt"
)

////////////////////////////////////////////////////////////////////////////////
// ICS02
Expand Down
8 changes: 7 additions & 1 deletion shared/core/types/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func NewError(code Code, msg string) Error {
}
}

// NextCode: 149
// NextCode: 150
type Code float64 // CONSIDERATION: Should these be a proto enum or a golang iota?

//nolint:gosec // G101 - Not hard-coded credentials
Expand Down Expand Up @@ -198,6 +198,7 @@ const (
CodeIBCStoreAlreadyExistsError Code = 146
CodeIBCStoreDoesNotExistError Code = 147
CodeIBCKeyDoesNotExistError Code = 148
CodeIBCClientNotActiveError Code = 149
)

const (
Expand Down Expand Up @@ -344,6 +345,7 @@ const (
IBCStoreAlreadyExistsError = "ibc store already exists in the store manager"
IBCStoreDoesNotExistError = "ibc store does not exist in the store manager"
IBCKeyDoesNotExistError = "key does not exist in the ibc store"
IBCClientNotActiveError = "ibc client is not active"
)

func ErrUnknownParam(paramName string) Error {
Expand Down Expand Up @@ -922,3 +924,7 @@ func ErrIBCStoreDoesNotExist(name string) Error {
func ErrIBCKeyDoesNotExist(key string) Error {
return NewError(CodeIBCKeyDoesNotExistError, fmt.Sprintf("%s: %s", IBCKeyDoesNotExistError, key))
}

func ErrIBCClientNotActive() Error {
return NewError(CodeIBCClientNotActiveError, IBCClientNotActiveError)
}
12 changes: 6 additions & 6 deletions shared/modules/ibc_client_module.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ type ClientManager interface {
// the ClientMessage can be verified using the existing ClientState and ConsensusState
UpdateClient(identifier string, clientMessage ClientMessage) error

// QueryConsensusState returns the ConsensusState at the given height for the given client
QueryConsensusState(identifier string, height Height) (ConsensusState, error)
// GetConsensusState returns the ConsensusState at the given height for the given client
GetConsensusState(identifier string, height Height) (ConsensusState, error)

// QueryClientState returns the ClientState for the given client
QueryClientState(identifier string) (ClientState, error)
// GetClientState returns the ClientState for the given client
GetClientState(identifier string) (ClientState, error)

// SubmitMisbehaviour submits evidence for a misbehaviour to the client, possibly invalidating
// previously valid state roots and thus preventing future updates
Expand Down Expand Up @@ -114,9 +114,9 @@ type ClientState interface {

// UpdateState updates and stores as necessary any associated information
// for an IBC client, such as the ClientState and corresponding ConsensusState.
// Upon successful update, a list of consensus heights is returned.
// Upon successful update, a consensus height is returned.
// It assumes the ClientMessage has already been verified.
UpdateState(clientStore ProvableStore, clientMsg ClientMessage) []Height
UpdateState(clientStore ProvableStore, clientMsg ClientMessage) Height
}

// ConsensusState is an interface that defines the methods required by a clients
Expand Down