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

Add back implementation #927

Draft
wants to merge 1 commit into
base: ibc/client-semantics-interface-only
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
74 changes: 74 additions & 0 deletions ibc/client/events.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package client

import (
client_types "github.com/pokt-network/pocket/ibc/client/types"
"github.com/pokt-network/pocket/shared/codec"
core_types "github.com/pokt-network/pocket/shared/core/types"
"github.com/pokt-network/pocket/shared/modules"
)

// emitCreateClientEvent emits a create client event
func (c *clientManager) emitCreateClientEvent(clientId string, clientState modules.ClientState) error {
return c.GetBus().GetEventLogger().EmitEvent(
&core_types.IBCEvent{
Topic: client_types.EventTopicCreateClient,
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().ToString())),
},
},
)
}

// emitUpdateClientEvent emits an update client event
func (c *clientManager) emitUpdateClientEvent(
clientId, clientType string,
consensusHeight modules.Height,
clientMessage modules.ClientMessage,
) error {
// Marshall the client message
clientMsgBz, err := codec.GetCodec().Marshal(clientMessage)
if err != nil {
return err
}

return c.GetBus().GetEventLogger().EmitEvent(
&core_types.IBCEvent{
Topic: client_types.EventTopicUpdateClient,
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.ToString())),
core_types.NewAttribute(client_types.AttributeKeyHeader, clientMsgBz),
},
},
)
}

// emitUpgradeClientEvent emits an upgrade client event
func (c *clientManager) emitUpgradeClientEvent(clientId string, clientState modules.ClientState) error {
return c.GetBus().GetEventLogger().EmitEvent(
&core_types.IBCEvent{
Topic: client_types.EventTopicUpdateClient,
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().ToString())),
},
},
)
}

// emitSubmitMisbehaviourEvent emits a submit misbehaviour event
func (c *clientManager) emitSubmitMisbehaviourEvent(clientId string, clientState modules.ClientState) error {
return c.GetBus().GetEventLogger().EmitEvent(
&core_types.IBCEvent{
Topic: client_types.EventTopicSubmitMisbehaviour,
Attributes: []*core_types.Attribute{
core_types.NewAttribute(client_types.AttributeKeyClientID, []byte(clientId)),
core_types.NewAttribute(client_types.AttributeKeyClientType, []byte(clientState.ClientType())),
},
},
)
}
151 changes: 151 additions & 0 deletions ibc/client/introspect.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
package client

import (
"errors"
"time"

light_client_types "github.com/pokt-network/pocket/ibc/client/light_clients/types"
"github.com/pokt-network/pocket/ibc/client/types"
ibc_types "github.com/pokt-network/pocket/ibc/types"
"github.com/pokt-network/pocket/shared/codec"
"github.com/pokt-network/pocket/shared/modules"
util_types "github.com/pokt-network/pocket/utility/types"
"google.golang.org/protobuf/types/known/durationpb"
)

// GetHostConsensusState returns the ConsensusState at the given height for the
// host chain, the Pocket network. It then serialises this and packs it into a
// ConsensusState object for use in a WASM client
func (c *clientManager) GetHostConsensusState(height modules.Height) (modules.ConsensusState, error) {
blockStore := c.GetBus().GetPersistenceModule().GetBlockStore()
block, err := blockStore.GetBlock(height.GetRevisionHeight())
if err != nil {
return nil, err
}
pocketConsState := &light_client_types.PocketConsensusState{
Timestamp: block.BlockHeader.Timestamp,
StateHash: block.BlockHeader.StateHash,
StateTreeHashes: block.BlockHeader.StateTreeHashes,
NextValSetHash: block.BlockHeader.NextValSetHash,
}
consBz, err := codec.GetCodec().Marshal(pocketConsState)
if err != nil {
return nil, err
}
return types.NewConsensusState(consBz, uint64(pocketConsState.Timestamp.AsTime().UnixNano())), nil
}

// GetHostClientState returns the ClientState at the given height for the host
// chain, the Pocket network.
//
// This function is used to validate the state of a client running on a
// counterparty chain.
func (c *clientManager) GetHostClientState(height modules.Height) (modules.ClientState, error) {
blockStore := c.GetBus().GetPersistenceModule().GetBlockStore()
block, err := blockStore.GetBlock(height.GetRevisionHeight())
if err != nil {
return nil, err
}
rCtx, err := c.GetBus().GetPersistenceModule().NewReadContext(int64(height.GetRevisionHeight()))
if err != nil {
return nil, err
}
defer rCtx.Release()
unbondingBlocks, err := rCtx.GetIntParam(util_types.ValidatorUnstakingBlocksParamName, int64(height.GetRevisionHeight()))
if err != nil {
return nil, err
}
// TODO_AFTER(#705): use the actual MinimumBlockTime once set
blockTime := time.Minute * 15
unbondingPeriod := blockTime * time.Duration(unbondingBlocks) // approx minutes per block * blocks
pocketClient := &light_client_types.PocketClientState{
NetworkId: block.BlockHeader.NetworkId,
TrustLevel: &light_client_types.Fraction{Numerator: 2, Denominator: 3},
TrustingPeriod: durationpb.New(unbondingPeriod),
UnbondingPeriod: durationpb.New(unbondingPeriod),
MaxClockDrift: durationpb.New(blockTime), // DISCUSS: What is a reasonable MaxClockDrift?
LatestHeight: &types.Height{
RevisionNumber: height.GetRevisionNumber(),
RevisionHeight: height.GetRevisionHeight(),
},
ProofSpec: ibc_types.SmtSpec,
}
clientBz, err := codec.GetCodec().Marshal(pocketClient)
if err != nil {
return nil, err
}
return &types.ClientState{
Data: clientBz,
RecentHeight: pocketClient.LatestHeight,
}, nil
}

// VerifyHostClientState verifies that a ClientState for a light client running
// on a counterparty chain is valid, by checking it against the result of
// GetHostClientState(counterpartyClientState.GetLatestHeight())
func (c *clientManager) VerifyHostClientState(counterparty modules.ClientState) error {
height, err := c.GetCurrentHeight()
if err != nil {
return err
}
hostState, err := c.GetHostClientState(height)
if err != nil {
return err
}
poktHost := new(light_client_types.PocketClientState)
err = codec.GetCodec().Unmarshal(hostState.GetData(), poktHost)
if err != nil {
return err
}
poktCounter := new(light_client_types.PocketClientState)
err = codec.GetCodec().Unmarshal(counterparty.GetData(), poktCounter)
if err != nil {
return errors.New("counterparty client state is not a PocketClientState")
}

if poktCounter.FrozenHeight > 0 {
return errors.New("counterparty client state is frozen")
}
if poktCounter.NetworkId != poktHost.NetworkId {
return errors.New("counterparty client state has different network id")
}
if poktCounter.LatestHeight.RevisionNumber != poktHost.LatestHeight.RevisionNumber {
return errors.New("counterparty client state has different revision number")
}
if poktCounter.GetLatestHeight().GTE(poktHost.GetLatestHeight()) {
return errors.New("counterparty client state has a height greater than or equal to the host client state")
}
if poktCounter.TrustLevel.LT(&light_client_types.Fraction{Numerator: 2, Denominator: 3}) ||
poktCounter.TrustLevel.GT(&light_client_types.Fraction{Numerator: 1, Denominator: 1}) {
return errors.New("counterparty client state trust level is not in the accepted range")
}
if !poktCounter.ProofSpec.ConvertToIcs23ProofSpec().SpecEquals(poktHost.ProofSpec.ConvertToIcs23ProofSpec()) {
return errors.New("counterparty client state has different proof spec")
}
if poktCounter.UnbondingPeriod != poktHost.UnbondingPeriod {
return errors.New("counterparty client state has different unbonding period")
}
if poktCounter.UnbondingPeriod.AsDuration().Nanoseconds() < poktHost.TrustingPeriod.AsDuration().Nanoseconds() {
return errors.New("counterparty client state unbonding period is less than trusting period")
}

// RESEARCH: Look into upgrade paths, their use and if they should just be equal

return nil
}

// GetCurrentHeight returns the current IBC client height of the network
// TODO_AFTER(#882): Use actual revision number
func (h *clientManager) GetCurrentHeight() (modules.Height, error) {
currHeight := h.GetBus().GetConsensusModule().CurrentHeight()
rCtx, err := h.GetBus().GetPersistenceModule().NewReadContext(int64(currHeight))
if err != nil {
return nil, err
}
defer rCtx.Release()
revNum := rCtx.GetRevisionNumber(int64(currHeight))
return &types.Height{
RevisionNumber: revNum,
RevisionHeight: currHeight,
}, nil
}
34 changes: 34 additions & 0 deletions ibc/client/queries.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package client

import (
"github.com/pokt-network/pocket/ibc/client/types"
"github.com/pokt-network/pocket/ibc/path"
core_types "github.com/pokt-network/pocket/shared/core/types"
"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 clientId prefixed client store
prefixed := path.ApplyPrefix(core_types.CommitmentPrefix(path.KeyClientStorePrefix), identifier)
clientStore, err := c.GetBus().GetIBCHost().GetProvableStore(string(prefixed))
if err != nil {
return nil, err
}

return types.GetConsensusState(clientStore, height)
}

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

return types.GetClientState(clientStore, identifier)
}
Loading