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

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
commit 04d969d797ae3baba7e8efbaecf5eb60766e22e1
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -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"

6 changes: 3 additions & 3 deletions ibc/client/events.go
Original file line number Diff line number Diff line change
@@ -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())),
},
},
)
@@ -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),
},
},
@@ -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())),
},
},
)
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
@@ -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"
)
@@ -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 {
@@ -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
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
8 changes: 7 additions & 1 deletion shared/core/types/error.go
Original file line number Diff line number Diff line change
@@ -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
@@ -198,6 +198,7 @@ const (
CodeIBCStoreAlreadyExistsError Code = 146
CodeIBCStoreDoesNotExistError Code = 147
CodeIBCKeyDoesNotExistError Code = 148
CodeIBCClientNotActiveError Code = 149
)

const (
@@ -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 {
@@ -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
@@ -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
@@ -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